Ejemplo n.º 1
0
		/**
		* Return a random BigInteger not less than 'min' and not greater than 'max'
		* 
		* @param min the least value that may be generated
		* @param max the greatest value that may be generated
		* @param random the source of randomness
		* @return a random BigInteger value in the range [min,max]
		*/
		public static BigInteger CreateRandomInRange(
			BigInteger		min,
			BigInteger		max,
			// TODO Should have been just Random class
			SecureRandom	random)
		{
			int cmp = min.CompareTo(max);
			if (cmp >= 0)
			{
				if (cmp > 0)
					throw new ArgumentException("'min' may not be greater than 'max'");

				return min;
			}

			if (min.BitLength > max.BitLength / 2)
			{
				return CreateRandomInRange(BigInteger.Zero, max.Subtract(min), random).Add(min);
			}

			for (int i = 0; i < MaxIterations; ++i)
			{
				BigInteger x = new BigInteger(max.BitLength, random);
				if (x.CompareTo(min) >= 0 && x.CompareTo(max) <= 0)
				{
					return x;
				}
			}

			// fall back to a faster (restricted) method
			return new BigInteger(max.Subtract(min).BitLength - 1, random).Add(min);
		}
Ejemplo n.º 2
0
		public RsaSecretBcpgKey(
			BigInteger d,
			BigInteger p,
			BigInteger q)
		{
			// PGP requires (p < q)
			int cmp = p.CompareTo(q);
			if (cmp >= 0)
			{
				if (cmp == 0)
					throw new ArgumentException("p and q cannot be equal");

				BigInteger tmp = p;
				p = q;
				q = tmp;
			}

			this.d = new MPInteger(d);
			this.p = new MPInteger(p);
			this.q = new MPInteger(q);
			this.u = new MPInteger(p.ModInverse(q));

			this.expP = d.Remainder(p.Subtract(BigInteger.One));
			this.expQ = d.Remainder(q.Subtract(BigInteger.One));
			this.crt = q.ModInverse(p);
		}
Ejemplo n.º 3
0
		/**
		 * generate a signature for the given message using the key we were
		 * initialised with. For conventional Gost3410 the message should be a Gost3411
		 * hash of the message of interest.
		 *
		 * @param message the message that will be verified later.
		 */
		public BigInteger[] GenerateSignature(
			byte[] message)
		{
			byte[] mRev = new byte[message.Length]; // conversion is little-endian
			for (int i = 0; i != mRev.Length; i++)
			{
				mRev[i] = message[mRev.Length - 1 - i];
			}

			BigInteger m = new BigInteger(1, mRev);
			Gost3410Parameters parameters = key.Parameters;
			BigInteger k;

			do
			{
				k = new BigInteger(parameters.Q.BitLength, random);
			}
			while (k.CompareTo(parameters.Q) >= 0);

			BigInteger r = parameters.A.ModPow(k, parameters.P).Mod(parameters.Q);

			BigInteger s = k.Multiply(m).
				Add(((Gost3410PrivateKeyParameters)key).X.Multiply(r)).
				Mod(parameters.Q);

			return new BigInteger[]{ r, s };
		}
		public AsymmetricCipherKeyPair GenerateKeyPair()
		{
			SecureRandom random = param.Random;
			Gost3410Parameters gost3410Params = param.Parameters;

			BigInteger q = gost3410Params.Q;
			BigInteger x;
			do
			{
				x = new BigInteger(256, random);
			}
			while (x.Sign < 1 || x.CompareTo(q) >= 0);

			BigInteger p = gost3410Params.P;
			BigInteger a = gost3410Params.A;

			// calculate the public key.
			BigInteger y = a.ModPow(x, p);

			if (param.PublicKeyParamSet != null)
			{
				return new AsymmetricCipherKeyPair(
					new Gost3410PublicKeyParameters(y, param.PublicKeyParamSet),
					new Gost3410PrivateKeyParameters(x, param.PublicKeyParamSet));
			}

			return new AsymmetricCipherKeyPair(
				new Gost3410PublicKeyParameters(y, gost3410Params),
				new Gost3410PrivateKeyParameters(x, gost3410Params));
		}
        public SecP384R1FieldElement(BigInteger x)
        {
            if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0)
                throw new ArgumentException("value invalid for SecP384R1FieldElement", "x");

            this.x = SecP384R1Field.FromBigInteger(x);
        }
		public Gost3410PublicKeyParameters(
			BigInteger			y,
			DerObjectIdentifier publicKeyParamSet)
			: base(false, publicKeyParamSet)
		{
			if (y.Sign < 1 || y.CompareTo(Parameters.P) >= 0)
				throw new ArgumentException("Invalid y for GOST3410 public key", "y");

			this.y = y;
		}
Ejemplo n.º 7
0
		public FpFieldElement(
			BigInteger	q,
			BigInteger	x)
		{
			if (x.CompareTo(q) >= 0)
				throw new ArgumentException("x value too large in field element");

			this.q = q;
			this.x = x;
		}
		public Gost3410PrivateKeyParameters(
			BigInteger			x,
			DerObjectIdentifier	publicKeyParamSet)
			: base(true, publicKeyParamSet)
		{
			if (x.Sign < 1 || x.BitLength > 256 || x.CompareTo(Parameters.Q) >= 0)
				throw new ArgumentException("Invalid x for GOST3410 private key", "x");

			this.x = x;
		}
Ejemplo n.º 9
0
		public DHParameters(
			BigInteger				p,
			BigInteger				g,
			BigInteger				q,
			int						m,
			int						l,
			BigInteger				j,
			DHValidationParameters	validation)
		{
			if (p == null)
				throw new ArgumentNullException("p");
			if (g == null)
				throw new ArgumentNullException("g");
			if (!p.TestBit(0))
				throw new ArgumentException("field must be an odd prime", "p");
			if (g.CompareTo(BigInteger.Two) < 0
				|| g.CompareTo(p.Subtract(BigInteger.Two)) > 0)
				throw new ArgumentException("generator must in the range [2, p - 2]", "g");
			if (q != null && q.BitLength >= p.BitLength)
				throw new ArgumentException("q too big to be a factor of (p-1)", "q");
			if (m >= p.BitLength)
				throw new ArgumentException("m value must be < bitlength of p", "m");
			if (l != 0)
			{ 
	            if (l >= p.BitLength)
                	throw new ArgumentException("when l value specified, it must be less than bitlength(p)", "l");
				if (l < m)
					throw new ArgumentException("when l value specified, it may not be less than m value", "l");
			}
			if (j != null && j.CompareTo(BigInteger.Two) < 0)
				throw new ArgumentException("subgroup factor must be >= 2", "j");

			// TODO If q, j both provided, validate p = jq + 1 ?

			this.p = p;
			this.g = g;
			this.q = q;
			this.m = m;
			this.l = l;
			this.j = j;
			this.validation = validation;
        }
 public override Number Calculate(BigInteger bigint1, BigInteger bigint2)
 {
     if (bigint1 == null || bigint2 == null)
     {
         return 0;
     }
     var comp = bigint2.CompareTo(BigInteger.Zero);
     if (comp == 0)
     {
         return 0;
     }
     if (comp < 0)
     {
         return bigint1.Negate().Mod(bigint2).Negate();
     }
     return bigint1.Mod(bigint2);
 }
Ejemplo n.º 11
0
		// 5.3 pg 28
		/**
		 * Generate a signature for the given message using the key we were
		 * initialised with. For conventional DSA the message should be a SHA-1
		 * hash of the message of interest.
		 *
		 * @param message the message that will be verified later.
		 */
		public BigInteger[] GenerateSignature(
			byte[] message)
		{
			BigInteger n = key.Parameters.N;
			BigInteger e = calculateE(n, message);

			BigInteger r = null;
			BigInteger s = null;

			// 5.3.2
			do // Generate s
			{
				BigInteger k = null;

				do // Generate r
				{
					do
					{
						k = new BigInteger(n.BitLength, random);
					}
					while (k.Sign == 0 || k.CompareTo(n) >= 0);

					ECPoint p = key.Parameters.G.Multiply(k);

					// 5.3.3
					BigInteger x = p.X.ToBigInteger();

					r = x.Mod(n);
				}
				while (r.Sign == 0);

				BigInteger d = ((ECPrivateKeyParameters)key).D;

				s = k.ModInverse(n).Multiply(e.Add(d.Multiply(r))).Mod(n);
			}
			while (s.Sign == 0);

			return new BigInteger[]{ r, s };
		}
Ejemplo n.º 12
0
		/**
		 * Generate a signature for the given message using the key we were
		 * initialised with. For conventional DSA the message should be a SHA-1
		 * hash of the message of interest.
		 *
		 * @param message the message that will be verified later.
		 */
		public BigInteger[] GenerateSignature(
			byte[] message)
		{
			DsaParameters parameters = key.Parameters;
			BigInteger q = parameters.Q;
			BigInteger m = calculateE(q, message);
			BigInteger k;

			do
			{
				k = new BigInteger(q.BitLength, random);
			}
			while (k.CompareTo(q) >= 0);

			BigInteger r = parameters.G.ModPow(k, parameters.P).Mod(q);

			k = k.ModInverse(q).Multiply(
				m.Add(((DsaPrivateKeyParameters)key).X.Multiply(r)));

			BigInteger s = k.Mod(q);

			return new BigInteger[]{ r, s };
		}
Ejemplo n.º 13
0
        /// <summary>
        /// Proving algorithm as specified in section 2.6.2 of the setup
        /// </summary>
        /// <param name="privKey">The secret key</param>
        /// <param name="setup">The setup parameters</param>
        /// <returns>List of signatures</returns>
        public static PermutationTestProof ProvePermutationTest(this RsaPrivateCrtKeyParameters privKey, PermutationTestSetup setup)
        {
            if (privKey == null)
            {
                throw new ArgumentNullException(nameof(privKey));
            }
            if (setup == null)
            {
                throw new ArgumentNullException(nameof(setup));
            }

            BigInteger p       = privKey.P;
            BigInteger q       = privKey.Q;
            BigInteger e       = privKey.PublicExponent;
            BigInteger Modulus = privKey.Modulus;

            var keyLength = Modulus.BitLength;
            var alpha     = setup.Alpha;

            BigInteger Two = BigInteger.Two;
            // 2^{|N| - 1}
            BigInteger lowerLimit = Two.Pow(keyLength - 1);
            // 2^{|N|}
            BigInteger upperLimit = Two.Pow(keyLength);

            // if N < 2^{KeySize-1}
            if (Modulus.CompareTo(lowerLimit) < 0)
            {
                throw new ArgumentOutOfRangeException("RSA modulus smaller than expected");
            }

            // if N >= 2^{KeySize}
            if (Modulus.CompareTo(upperLimit) >= 0)
            {
                throw new ArgumentOutOfRangeException("RSA modulus larger than expected");
            }

            // Verify alpha and N
            if (!CheckAlphaN(alpha, Modulus))
            {
                throw new ArgumentException("RSA modulus has a small prime factor");
            }

            var psBytes = setup.PublicString;
            var k       = setup.SecurityParameter;

            byte[][] sigs;

            // Generate m1 and m2
            Get_m1_m2((decimal)alpha, e.IntValue, k, out int m1, out int m2);

            // Calculate eN
            var eN = Modulus.Multiply(e);

            // Generate a pair (pub, sec) of keys with eN as e.
            var keyPrimePair = Utils.GeneratePrivate(p, q, eN);

            // Extract public key (N, e) from private key.
            var pubKey = privKey.ToPublicKey();

            // Generate list of rho values
            GetRhos(m2, psBytes, pubKey, keyLength, out byte[][] rhoValues);

            // Signing the Rho values
            sigs = new byte[m2][];
            for (int i = 0; i < m2; i++)
            {
                if (i <= m1)
                {
                    sigs[i] = ((RsaPrivateCrtKeyParameters)keyPrimePair.Private).Decrypt(rhoValues[i]);
                }
                else
                {
                    sigs[i] = privKey.Decrypt(rhoValues[i]);
                }
            }
            return(new PermutationTestProof(sigs));
        }
		/**
		 * Procedure C
		 * procedure generates the a value from the given p,q,
		 * returning the a value.
		 */
		private BigInteger procedure_C(BigInteger p, BigInteger q)
		{
			BigInteger pSub1 = p.Subtract(BigInteger.One);
			BigInteger pSub1Divq = pSub1.Divide(q);

			for(;;)
			{
				BigInteger d = new BigInteger(p.BitLength, init_random);

				// 1 < d < p-1
				if (d.CompareTo(BigInteger.One) > 0 && d.CompareTo(pSub1) < 0)
				{
					BigInteger a = d.ModPow(pSub1Divq, p);

					if (a.CompareTo(BigInteger.One) != 0)
					{
						return a;
					}
				}
			}
		}
Ejemplo n.º 15
0
        /**
         * which Generates the p and g values from the given parameters,
         * returning the DsaParameters object.
         * <p>
         * Note: can take a while...</p>
         */
        public DsaParameters GenerateParameters()
        {
            byte[]     seed  = new byte[20];
            byte[]     part1 = new byte[20];
            byte[]     part2 = new byte[20];
            byte[]     u     = new byte[20];
            Sha1Digest sha1  = new Sha1Digest();
            int        n     = (size - 1) / 160;

            byte[] w = new byte[size / 8];

            BigInteger q = null, p = null, g = null;
            int        counter     = 0;
            bool       primesFound = false;

            while (!primesFound)
            {
                do
                {
                    random.NextBytes(seed);

                    sha1.BlockUpdate(seed, 0, seed.Length);

                    sha1.DoFinal(part1, 0);

                    Array.Copy(seed, 0, part2, 0, seed.Length);

                    Add(part2, seed, 1);

                    sha1.BlockUpdate(part2, 0, part2.Length);

                    sha1.DoFinal(part2, 0);

                    for (int i = 0; i != u.Length; i++)
                    {
                        u[i] = (byte)(part1[i] ^ part2[i]);
                    }

                    u[0]  |= (byte)0x80;
                    u[19] |= (byte)0x01;

                    q = new BigInteger(1, u);
                }while (!q.IsProbablePrime(certainty));

                counter = 0;

                int offset = 2;

                while (counter < 4096)
                {
                    for (int k = 0; k < n; k++)
                    {
                        Add(part1, seed, offset + k);
                        sha1.BlockUpdate(part1, 0, part1.Length);
                        sha1.DoFinal(part1, 0);
                        Array.Copy(part1, 0, w, w.Length - (k + 1) * part1.Length, part1.Length);
                    }

                    Add(part1, seed, offset + n);
                    sha1.BlockUpdate(part1, 0, part1.Length);
                    sha1.DoFinal(part1, 0);
                    Array.Copy(part1, part1.Length - ((w.Length - (n) * part1.Length)), w, 0, w.Length - n * part1.Length);

                    w[0] |= (byte)0x80;

                    BigInteger x = new BigInteger(1, w);

                    BigInteger c = x.Mod(q.ShiftLeft(1));

                    p = x.Subtract(c.Subtract(BigInteger.One));

                    if (p.TestBit(size - 1))
                    {
                        if (p.IsProbablePrime(certainty))
                        {
                            primesFound = true;
                            break;
                        }
                    }

                    counter += 1;
                    offset  += n + 1;
                }
            }

            //
            // calculate the generator g
            //
            BigInteger pMinusOneOverQ = p.Subtract(BigInteger.One).Divide(q);

            for (;;)
            {
                BigInteger h = new BigInteger(size, random);
                if (h.CompareTo(BigInteger.One) <= 0 || h.CompareTo(p.Subtract(BigInteger.One)) >= 0)
                {
                    continue;
                }

                g = h.ModPow(pMinusOneOverQ, p);
                if (g.CompareTo(BigInteger.One) <= 0)
                {
                    continue;
                }

                break;
            }

            return(new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter)));
        }
Ejemplo n.º 16
0
 public static int Compare(BigInteger x, BigInteger y) {
     return x.CompareTo(y);
 }
Ejemplo n.º 17
0
        private static void VerifyComparison(BigInteger x, bool IsXNegative, BigInteger y, bool IsYNegative, int expectedResult)
        {
            bool expectedEquals = 0 == expectedResult;
            bool expectedLessThan = expectedResult < 0;
            bool expectedGreaterThan = expectedResult > 0;

            if (IsXNegative == true)
            {
                x = x * -1;
            }
            if (IsYNegative == true)
            {
                y = y * -1;
            }

            Assert.Equal(expectedEquals, x == y);
            Assert.Equal(expectedEquals, y == x);

            Assert.Equal(!expectedEquals, x != y);
            Assert.Equal(!expectedEquals, y != x);

            Assert.Equal(expectedEquals, x.Equals(y));
            Assert.Equal(expectedEquals, y.Equals(x));

            Assert.Equal(expectedEquals, x.Equals((Object)y));
            Assert.Equal(expectedEquals, y.Equals((Object)x));

            VerifyCompareResult(expectedResult, x.CompareTo(y), "x.CompareTo(y)");
            VerifyCompareResult(-expectedResult, y.CompareTo(x), "y.CompareTo(x)");

            if (expectedEquals)
            {
                Assert.Equal(x.GetHashCode(), y.GetHashCode());
                Assert.Equal(x.ToString(), y.ToString());
            }

            Assert.Equal(x.GetHashCode(), x.GetHashCode());
            Assert.Equal(y.GetHashCode(), y.GetHashCode());

            Assert.Equal(expectedLessThan, x < y);
            Assert.Equal(expectedGreaterThan, y < x);

            Assert.Equal(expectedGreaterThan, x > y);
            Assert.Equal(expectedLessThan, y > x);

            Assert.Equal(expectedLessThan || expectedEquals, x <= y);
            Assert.Equal(expectedGreaterThan || expectedEquals, y <= x);

            Assert.Equal(expectedGreaterThan || expectedEquals, x >= y);
            Assert.Equal(expectedLessThan || expectedEquals, y >= x);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Extract the truncated square root of a BigInteger
        /// </summary>
        /// 
        /// <param name="X">A value out of which we extract the square root</param>
        /// 
        /// <returns>Returns the truncated square root of <c>a</c></returns>
        public static BigInteger SquareRoot(BigInteger X)
        {
            int bl;
            BigInteger result, remainder, b;

            if (X.CompareTo(ZERO) < 0)
                throw new ArithmeticException("Cannot extract root of negative number" + X + "!");

            bl = X.BitLength;
            result = ZERO;
            remainder = ZERO;

            // if the bit length is odd then extra step
            if ((bl & 1) != 0)
            {
                result = result.Add(ONE);
                bl--;
            }

            while (bl > 0)
            {
                remainder = remainder.Multiply(FOUR);
                remainder = remainder.Add(BigInteger.ValueOf((X.TestBit(--bl) ? 2 : 0) + (X.TestBit(--bl) ? 1 : 0)));
                b = result.Multiply(FOUR).Add(ONE);
                result = result.Multiply(TWO);

                if (remainder.CompareTo(b) != -1)
                {
                    result = result.Add(ONE);
                    remainder = remainder.Subtract(b);
                }
            }

            return result;
        }
Ejemplo n.º 19
0
        //проверка простоты методом Миллера — Рабина
        public static bool checkSimplicity(BigInteger n, KeyAmount keyAmount)
        {
            int k = (int)keyAmount;         //размерность ключа

            //исключаем числа делимые на простые числа от 2 до 256 либо к
            int[] simpleNumberForCheck = getSimplicityNumbers(k <= 256 ? 256 : k);
            for (int i = 0; i < simpleNumberForCheck.Length; i++)
            {
                BigInteger remainder;
                BigInteger.DivRem(n, new BigInteger(simpleNumberForCheck[i]), out remainder);
                if (remainder.IsZero || n.CompareTo(new BigInteger(simpleNumberForCheck[i])) == 0)
                {
                    return(false);
                }
            }

            Random     rnd = new Random();
            int        s   = 0;
            BigInteger nmm = BigInteger.Subtract(n, BigInteger.One);
            BigInteger t   = nmm;

            //вычисляем коэффициенты t и s
            do
            {
                t = BigInteger.Divide(t, new BigInteger(2));
                s++;
                BigInteger remainder;
                BigInteger.DivRem(t, new BigInteger(2), out remainder);
                if (remainder != 0)
                {
                    break;
                }
            } while (true);

            //проверяем условия простоты
            int kk = 30720 / k;

            for (int i = 0; i < kk; i++)
            {
                BigInteger a;
                for (;;)
                {
                    a = rnd.NextBigInteger(n);
                    if (nmm.CompareTo(a) > 0 && a.CompareTo(new BigInteger(2)) >= 0)
                    {
                        break;
                    }
                }
                //проверяем сравнимость по модулю
                BigInteger x = BigInteger.ModPow(a, t, n);
                if (x.IsOne || x.CompareTo(nmm) == 0)
                {
                    continue;
                }
                for (int j = 1; j < s; j++)
                {
                    x = BigInteger.ModPow(x, new BigInteger(2), n);
                    if (x.IsOne)
                    {
                        return(false);                              //составное
                    }
                    if (x.CompareTo(nmm) == 0)
                    {
                        goto ff;                                    //перейти на следующую проверку
                    }
                }
                return(false);                                       //составное

                ff :;
            }
            return(true);
        }
        // Stratis kernel protocol
        // coinstake must meet hash target according to the protocol:
        // kernel (input 0) must meet the formula
        //     hash(nStakeModifier + txPrev.block.nTime + txPrev.nTime + txPrev.vout.hash + txPrev.vout.n + nTime) < bnTarget * nWeight
        // this ensures that the chance of getting a coinstake is proportional to the
        // amount of coins one owns.
        // The reason this hash is chosen is the following:
        //   nStakeModifier: scrambles computation to make it very difficult to precompute
        //                   future proof-of-stake
        //   txPrev.block.nTime: prevent nodes from guessing a good timestamp to
        //                       generate transaction for future advantage,
        //                       obsolete since v3
        //   txPrev.nTime: slightly scrambles computation
        //   txPrev.vout.hash: hash of txPrev, to reduce the chance of nodes
        //                     generating coinstake at the same time
        //   txPrev.vout.n: output number of txPrev, to reduce the chance of nodes
        //                  generating coinstake at the same time
        //   nTime: current timestamp
        //   block/tx hash should not be used here as they can be generated in vast
        //   quantities so as to generate blocks faster, degrading the system back into
        //   a proof-of-work situation.
        //
        private void CheckStakeKernelHashV2(ContextInformation context, ChainedBlock pindexPrev, uint nBits,
                                            uint nTimeBlockFrom,
                                            BlockStake prevBlockStake, UnspentOutputs txPrev, OutPoint prevout, uint nTimeTx)
        {
            if (nTimeTx < txPrev.Time)
            {
                ConsensusErrors.StakeTimeViolation.Throw();
            }

            // Base target
            var bnTarget = new Target(nBits).ToBigInteger();

            // TODO: Investigate:
            // The POS protocol should probably put a limit on the max amount that can be staked
            // not a hard limit but a limit that allow any amount to be staked with a max weight value.
            // the max weight should not exceed the max uint256 array size (array siez = 32)

            // Weighted target
            var nValueIn = txPrev._Outputs[prevout.N].Value.Satoshi;
            var bnWeight = BigInteger.ValueOf(nValueIn);

            bnTarget = bnTarget.Multiply(bnWeight);

            context.Stake.TargetProofOfStake = ToUInt256(bnTarget);

            var     nStakeModifier       = prevBlockStake.StakeModifier;   //pindexPrev.Header.BlockStake.StakeModifier;
            uint256 bnStakeModifierV2    = prevBlockStake.StakeModifierV2; //pindexPrev.Header.BlockStake.StakeModifierV2;
            int     nStakeModifierHeight = pindexPrev.Height;
            var     nStakeModifierTime   = pindexPrev.Header.Time;

            // Calculate hash
            using (var ms = new MemoryStream())
            {
                var serializer = new BitcoinStream(ms, true);
                if (IsProtocolV3((int)nTimeTx))
                {
                    serializer.ReadWrite(bnStakeModifierV2);
                }
                else
                {
                    serializer.ReadWrite(nStakeModifier);
                    serializer.ReadWrite(nTimeBlockFrom);
                }

                serializer.ReadWrite(txPrev.Time);
                serializer.ReadWrite(prevout.Hash);
                serializer.ReadWrite(prevout.N);
                serializer.ReadWrite(nTimeTx);

                context.Stake.HashProofOfStake = Hashes.Hash256(ms.ToArray());
            }

            //LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n",
            //	nStakeModifier, nStakeModifierHeight,
            //	DateTimeStrFormat(nStakeModifierTime),

            //	DateTimeStrFormat(nTimeBlockFrom));

            //LogPrintf("CheckStakeKernelHash() : check modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n",
            //	nStakeModifier,
            //	nTimeBlockFrom, txPrev.nTime, prevout.n, nTimeTx,
            //	hashProofOfStake.ToString());

            // Now check if proof-of-stake hash meets target protocol
            var hashProofOfStakeTarget = new BigInteger(1, context.Stake.HashProofOfStake.ToBytes(false));

            if (hashProofOfStakeTarget.CompareTo(bnTarget) > 0)
            {
                ConsensusErrors.StakeHashInvalidTarget.Throw();
            }

            //  if (fDebug && !fPrintProofOfStake)
            //  {
            //		LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n",
            //		nStakeModifier, nStakeModifierHeight,
            //		DateTimeStrFormat(nStakeModifierTime),

            //		DateTimeStrFormat(nTimeBlockFrom));

            //		LogPrintf("CheckStakeKernelHash() : pass modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n",
            //		nStakeModifier,
            //		nTimeBlockFrom, txPrev.nTime, prevout.n, nTimeTx,
            //		hashProofOfStake.ToString());
            //  }
        }
Ejemplo n.º 21
0
        /**
         * Process a single block using the basic ElGamal algorithm.
         *
         * @param in the input array.
         * @param inOff the offset into the input buffer where the data starts.
         * @param length the length of the data to be processed.
         * @return the result of the ElGamal process.
         * @exception DataLengthException the input block is too large.
         */
        public byte[] ProcessBlock(
            byte[]  input,
            int inOff,
            int length)
        {
            if (key == null)
            {
                throw new InvalidOperationException("ElGamal engine not initialised");
            }

            int maxLength = forEncryption
                                ?       (bitSize - 1 + 7) / 8
                                :       GetInputBlockSize();

            if (length > maxLength)
            {
                throw new DataLengthException("input too large for ElGamal cipher.\n");
            }

            BigInteger p = key.Parameters.P;

            byte[] output;
            if (key is ElGamalPrivateKeyParameters)             // decryption
            {
                int        halfLength = length / 2;
                BigInteger gamma      = new BigInteger(1, input, inOff, halfLength);
                BigInteger phi        = new BigInteger(1, input, inOff + halfLength, halfLength);

                ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters)key;

                // a shortcut, which generally relies on p being prime amongst other things.
                // if a problem with this shows up, check the p and g values!
                BigInteger m = gamma.ModPow(p.Subtract(BigInteger.One).Subtract(priv.X), p).Multiply(phi).Mod(p);

                output = m.ToByteArrayUnsigned();
            }
            else             // encryption
            {
                BigInteger tmp = new BigInteger(1, input, inOff, length);

                if (tmp.BitLength >= p.BitLength)
                {
                    throw new DataLengthException("input too large for ElGamal cipher.\n");
                }


                ElGamalPublicKeyParameters pub = (ElGamalPublicKeyParameters)key;

                BigInteger pSub2 = p.Subtract(BigInteger.Two);

                // TODO In theory, a series of 'k', 'g.ModPow(k, p)' and 'y.ModPow(k, p)' can be pre-calculated
                BigInteger k;
                do
                {
                    k = new BigInteger(p.BitLength, random);
                }while (k.SignValue == 0 || k.CompareTo(pSub2) > 0);

                BigInteger g     = key.Parameters.G;
                BigInteger gamma = g.ModPow(k, p);
                BigInteger phi   = tmp.Multiply(pub.Y.ModPow(k, p)).Mod(p);

                output = new byte[this.GetOutputBlockSize()];

                // TODO Add methods to allow writing BigInteger to existing byte array?
                byte[] out1 = gamma.ToByteArrayUnsigned();
                byte[] out2 = phi.ToByteArrayUnsigned();
                out1.CopyTo(output, output.Length / 2 - out1.Length);
                out2.CopyTo(output, output.Length - out2.Length);
            }

            return(output);
        }
Ejemplo n.º 22
0
 public static int Compare(BigInteger x, BigInteger y)
 {
     return(x.CompareTo(y));
 }
Ejemplo n.º 23
0
        /**
         * FIPS 186-4 C.3.2 Enhanced Miller-Rabin Probabilistic Primality Test
         *
         * Run several iterations of the Miller-Rabin algorithm with randomly-chosen bases. This is an
         * alternative to {@link #isMRProbablePrime(BigInteger, SecureRandom, int)} that provides more
         * information about a composite candidate, which may be useful when generating or validating
         * RSA moduli.
         *
         * @param candidate
         *            the {@link BigInteger} instance to test for primality.
         * @param random
         *            the source of randomness to use to choose bases.
         * @param iterations
         *            the number of randomly-chosen bases to perform the test for.
         * @return an {@link MROutput} instance that can be further queried for details.
         */
        public static MROutput EnhancedMRProbablePrimeTest(BigInteger candidate, SecureRandom random, int iterations)
        {
            CheckCandidate(candidate, "candidate");

            if (random == null)
            {
                throw new ArgumentNullException("random");
            }
            if (iterations < 1)
            {
                throw new ArgumentException("must be > 0", "iterations");
            }

            if (candidate.BitLength == 2)
            {
                return(MROutput.ProbablyPrime());
            }

            if (!candidate.TestBit(0))
            {
                return(MROutput.ProvablyCompositeWithFactor(Two));
            }

            BigInteger w       = candidate;
            BigInteger wSubOne = candidate.Subtract(One);
            BigInteger wSubTwo = candidate.Subtract(Two);

            int        a = wSubOne.GetLowestSetBit();
            BigInteger m = wSubOne.ShiftRight(a);

            for (int i = 0; i < iterations; ++i)
            {
                BigInteger b = BigIntegers.CreateRandomInRange(Two, wSubTwo, random);
                BigInteger g = b.Gcd(w);

                if (g.CompareTo(One) > 0)
                {
                    return(MROutput.ProvablyCompositeWithFactor(g));
                }

                BigInteger z = b.ModPow(m, w);

                if (z.Equals(One) || z.Equals(wSubOne))
                {
                    continue;
                }

                bool primeToBase = false;

                BigInteger x = z;
                for (int j = 1; j < a; ++j)
                {
                    z = z.ModPow(Two, w);

                    if (z.Equals(wSubOne))
                    {
                        primeToBase = true;
                        break;
                    }

                    if (z.Equals(One))
                    {
                        break;
                    }

                    x = z;
                }

                if (!primeToBase)
                {
                    if (!z.Equals(One))
                    {
                        x = z;
                        z = z.ModPow(Two, w);

                        if (!z.Equals(One))
                        {
                            x = z;
                        }
                    }

                    g = x.Subtract(One).Gcd(w);

                    if (g.CompareTo(One) > 0)
                    {
                        return(MROutput.ProvablyCompositeWithFactor(g));
                    }

                    return(MROutput.ProvablyCompositeNotPrimePower());
                }
            }

            return(MROutput.ProbablyPrime());
        }
Ejemplo n.º 24
0
 /// <summary>
 /// Returns true if this objects chainWork is higher than the others.
 /// </summary>
 public bool MoreWorkThan(StoredBlock other)
 {
     return(_chainWork.CompareTo(other._chainWork) > 0);
 }
Ejemplo n.º 25
0
        /**
         * return a sqrt root - the routine verifies that the calculation
         * returns the right value - if none exists it returns null.
         */
        public override ECFieldElement Sqrt()
        {
            if (IsZero || IsOne)
            {
                return(this);
            }

            if (!q.TestBit(0))
            {
                throw Platform.CreateNotImplementedException("even value of q");
            }

            if (q.TestBit(1)) // q == 4m + 3
            {
                BigInteger e = q.ShiftRight(2).Add(BigInteger.One);
                return(CheckSqrt(new FpFieldElement(q, r, x.ModPow(e, q))));
            }

            if (q.TestBit(2)) // q == 8m + 5
            {
                BigInteger t1 = x.ModPow(q.ShiftRight(3), q);
                BigInteger t2 = ModMult(t1, x);
                BigInteger t3 = ModMult(t2, t1);

                if (t3.Equals(BigInteger.One))
                {
                    return(CheckSqrt(new FpFieldElement(q, r, t2)));
                }

                // TODO This is constant and could be precomputed
                BigInteger t4 = BigInteger.Two.ModPow(q.ShiftRight(2), q);

                BigInteger y = ModMult(t2, t4);

                return(CheckSqrt(new FpFieldElement(q, r, y)));
            }

            // q == 8m + 1

            BigInteger legendreExponent = q.ShiftRight(1);

            if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
            {
                return(null);
            }

            BigInteger X     = this.x;
            BigInteger fourX = ModDouble(ModDouble(X));;

            BigInteger k = legendreExponent.Add(BigInteger.One), qMinusOne = q.Subtract(BigInteger.One);

            BigInteger U, V;
            Random     rand = new Random();

            do
            {
                BigInteger P;
                do
                {
                    P = new BigInteger(q.BitLength, rand);
                }while (P.CompareTo(q) >= 0 ||
                        !ModReduce(P.Multiply(P).Subtract(fourX)).ModPow(legendreExponent, q).Equals(qMinusOne));

                BigInteger[] result = LucasSequence(P, X, k);
                U = result[0];
                V = result[1];

                if (ModMult(V, V).Equals(fourX))
                {
                    return(new FpFieldElement(q, r, ModHalfAbs(V)));
                }
            }while (U.Equals(BigInteger.One) || U.Equals(qMinusOne));

            return(null);
        }
Ejemplo n.º 26
0
        /**
         * return a sqrt root - the routine verifies that the calculation
         * returns the right value - if none exists it returns null.
         */
        public override ECFieldElement Sqrt()
        {
            if (IsZero || IsOne)
                return this;

            if (!q.TestBit(0))
                throw Platform.CreateNotImplementedException("even value of q");

            if (q.TestBit(1)) // q == 4m + 3
            {
                BigInteger e = q.ShiftRight(2).Add(BigInteger.One);
                return CheckSqrt(new FpFieldElement(q, r, x.ModPow(e, q)));
            }

            if (q.TestBit(2)) // q == 8m + 5
            {
                BigInteger t1 = x.ModPow(q.ShiftRight(3), q);
                BigInteger t2 = ModMult(t1, x);
                BigInteger t3 = ModMult(t2, t1);

                if (t3.Equals(BigInteger.One))
                {
                    return CheckSqrt(new FpFieldElement(q, r, t2));
                }

                // TODO This is constant and could be precomputed
                BigInteger t4 = BigInteger.Two.ModPow(q.ShiftRight(2), q);

                BigInteger y = ModMult(t2, t4);

                return CheckSqrt(new FpFieldElement(q, r, y));
            }

            // q == 8m + 1

            BigInteger legendreExponent = q.ShiftRight(1);
            if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
                return null;

            BigInteger X = this.x;
            BigInteger fourX = ModDouble(ModDouble(X)); ;

            BigInteger k = legendreExponent.Add(BigInteger.One), qMinusOne = q.Subtract(BigInteger.One);

            BigInteger U, V;
            Random rand = new Random();
            do
            {
                BigInteger P;
                do
                {
                    P = new BigInteger(q.BitLength, rand);
                }
                while (P.CompareTo(q) >= 0
                    || !ModReduce(P.Multiply(P).Subtract(fourX)).ModPow(legendreExponent, q).Equals(qMinusOne));

                BigInteger[] result = LucasSequence(P, X, k);
                U = result[0];
                V = result[1];

                if (ModMult(V, V).Equals(fourX))
                {
                    return new FpFieldElement(q, r, ModHalfAbs(V));
                }
            }
            while (U.Equals(BigInteger.One) || U.Equals(qMinusOne));

            return null;
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Create a random BigInteger
        /// </summary>
        /// 
        /// <param name="UpperBound">The upper bound</param>
        /// <param name="SecRnd">An instance of the SecureRandom class</param>
        /// 
        /// <returns>A random BigInteger</returns>
        public static BigInteger Randomize(BigInteger UpperBound, SecureRandom SecRnd)
        {
            int blen = UpperBound.BitLength;
            BigInteger randomNum = BigInteger.ValueOf(0);

            if (SecRnd == null)
                SecRnd = _secRnd != null ? _secRnd : new SecureRandom();

            for (int i = 0; i < 20; i++)
            {
                randomNum = new BigInteger(blen, SecRnd);
                if (randomNum.CompareTo(UpperBound) < 0)
                    return randomNum;
            }

            return randomNum.Mod(UpperBound);
        }
Ejemplo n.º 28
0
 /**
  * @return true if the S component is "low", that means it is below
  * {@link ECKeyPair#HALF_CURVE_ORDER}. See
  * <a href="https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#Low_S_values_in_signatures">
  * BIP62</a>.
  */
 private bool IsCanonical()
 {
     return(S.CompareTo(ECKeyPair.HalfCurveOrder) <= 0);
 }
Ejemplo n.º 29
0
            /*  ----------------------------------------------------------------------------
                DblToRgbPrecise()

                Uses big integer arithmetic to get the sequence of digits.
            */
            public static void DblToRgbPrecise(double dbl, byte[] mantissa, out int exponent, out int mantissaSize) {
                BigInteger biNum = new BigInteger();
                BigInteger biDen = new BigInteger();
                BigInteger biHi  = new BigInteger();
                BigInteger biLo  = new BigInteger();
                BigInteger biT   = new BigInteger();
                BigInteger biHiLo;
                byte bT;
                bool fPow2;
                int ib, cu;
                int wExp10, wExp2, w1, w2;
                int c2Num, c2Den, c5Num, c5Den;
                double dblT;
                //uint *rgu = stackalloc uint[2];
                uint rgu0, rgu1;
                uint dblHi, dblLo;

                dblHi = DblHi(dbl);
                dblLo = DblLo(dbl);

                // Caller should take care of 0, negative and non-finite values.
                Debug.Assert(!IsSpecial(dbl));
                Debug.Assert(0 < dbl);

                // Init the Denominator, Hi error and Lo error bigints.
                biDen.InitFromDigits(1, 0, 1);
                biHi.InitFromDigits(1, 0, 1);

                wExp2 = (int)(((dblHi & 0x7FF00000) >> 20) - 1075);
                rgu1 = dblHi & 0x000FFFFF;
                rgu0 = dblLo;
                cu = 2;
                fPow2 = false;
                if (wExp2 == -1075) {
                    // dbl is denormalized.
                    Debug.Assert(0 == (dblHi & 0x7FF00000));
                    if (0 == rgu1) {
                        cu = 1;
                    }

                    // Get dblT such that dbl / dblT is a power of 2 and 1 <= dblT < 2.
                    // First multiply by a power of 2 to get a normalized value.
                    dblT = BitConverter.Int64BitsToDouble(0x4FF00000L << 32);
                    dblT *= dbl;
                    Debug.Assert(0 != (DblHi(dblT) & 0x7FF00000));

                    // This is the power of 2.
                    w1 = (int)((DblHi(dblT) & 0x7FF00000) >> 20) - (256 + 1023);

                    dblHi = DblHi(dblT);
                    dblHi &= 0x000FFFFF;
                    dblHi |= 0x3FF00000;
                    dblT = BitConverter.Int64BitsToDouble((long)dblHi << 32 | DblLo(dblT));

                    // Adjust wExp2 because we don't have the implicit bit.
                    wExp2++;
                } else {
                    // Get dblT such that dbl / dblT is a power of 2 and 1 <= dblT < 2.
                    // First multiply by a power of 2 to get a normalized value.
                    dblHi &= 0x000FFFFF;
                    dblHi |= 0x3FF00000;
                    dblT = BitConverter.Int64BitsToDouble((long)dblHi << 32 | dblLo);

                    // This is the power of 2.
                    w1 = wExp2 + 52;

                    if (0 == rgu0 && 0 == rgu1 && wExp2 > -1074) {
                        // Power of 2 bigger than smallest normal. The next smaller
                        // representable value is closer than the next larger value.
                        rgu1 = 0x00200000;
                        wExp2--;
                        fPow2 = true;
                    } else {
                        // Normalized and not a power of 2 or the smallest normal. The
                        // representable values on either side are the same distance away.
                        rgu1 |= 0x00100000;
                    }
                }

                // Compute an approximation to the base 10 log. This is borrowed from
                // David ----'s paper.
                Debug.Assert(1 <= dblT && dblT < 2);
                dblT = (dblT - 1.5) * 0.289529654602168 + 0.1760912590558 +
                    w1 * 0.301029995663981;
                wExp10 = (int)dblT;
                if (dblT < 0 && dblT != wExp10) {
                    wExp10--;
                }

                if (wExp2 >= 0) {
                    c2Num = wExp2;
                    c2Den = 0;
                } else {
                    c2Num = 0;
                    c2Den = -wExp2;
                }

                if (wExp10 >= 0) {
                    c5Num = 0;
                    c5Den = wExp10;
                    c2Den += wExp10;
                } else {
                    c2Num -= wExp10;
                    c5Num = -wExp10;
                    c5Den = 0;
                }

                if (c2Num > 0 && c2Den > 0) {
                    w1 = c2Num < c2Den ? c2Num : c2Den;
                    c2Num -= w1;
                    c2Den -= w1;
                }
                // We need a bit for the Hi and Lo values.
                c2Num++;
                c2Den++;

                // Initialize biNum and multiply by powers of 5.
                if (c5Num > 0) {
                    Debug.Assert(0 == c5Den);
                    biHi.MulPow5(c5Num);
                    biNum.InitFromBigint(biHi);
                    if (1 == cu) {
                        biNum.MulAdd(rgu0, 0);
                    } else {
                        biNum.MulAdd(rgu1, 0);
                        biNum.ShiftLeft(32);
                        if (0 != rgu0) {
                            biT.InitFromBigint(biHi);
                            biT.MulAdd(rgu0, 0);
                            biNum.Add(biT);
                        }
                    }
                } else {
                    Debug.Assert(cu <= 2);
                    biNum.InitFromDigits(rgu0, rgu1, cu);
                    if (c5Den > 0) {
                        biDen.MulPow5(c5Den);
                    }
                }

                // BigInteger.DivRem only works if the 4 high bits of the divisor are 0.
                // It works most efficiently if there are exactly 4 zero high bits.
                // Adjust c2Den and c2Num to guarantee this.
                w1 = CbitZeroLeft(biDen[biDen.Length - 1]);
                w1 = (w1 + 28 - c2Den) & 0x1F;
                c2Num += w1;
                c2Den += w1;

                // Multiply by powers of 2.
                Debug.Assert(c2Num > 0 && c2Den > 0);
                biNum.ShiftLeft(c2Num);
                if (c2Num > 1) {
                    biHi.ShiftLeft(c2Num - 1);
                }
                biDen.ShiftLeft(c2Den);
                Debug.Assert(0 == (biDen[biDen.Length - 1] & 0xF0000000));
                Debug.Assert(0 != (biDen[biDen.Length - 1] & 0x08000000));

                // Get biHiLo and handle the power of 2 case where biHi needs to be doubled.
                if (fPow2) {
                    biHiLo = biLo;
                    biHiLo.InitFromBigint(biHi);
                    biHi.ShiftLeft(1);
                } else {
                    biHiLo = biHi;
                }

                for (ib = 0; ; ) {
                    bT = (byte)biNum.DivRem(biDen);
                    if (0 == ib && 0 == bT) {
                        // Our estimate of wExp10 was too big. Oh well.
                        wExp10--;
                        goto LSkip;
                    }

                    // w1 = sign(biNum - biHiLo).
                    w1 = biNum.CompareTo(biHiLo);

                    // w2 = sign(biNum + biHi - biDen).
                    if (biDen.CompareTo(biHi) < 0) {
                        w2 = 1;
                    } else {
                        // 
                        biT.InitFromBigint(biDen);
                        biT.Subtract(biHi);
                        w2 = biNum.CompareTo(biT);
                    }

                    // if (biNum + biHi == biDen && even)
                    if (0 == w2 && 0 == (dblLo & 1)) {
                        // Rounding up this digit produces exactly (biNum + biHi) which
                        // StrToDbl will round down to dbl.
                        if (bT == 9) {
                            goto LRoundUp9;
                        }
                        if (w1 > 0) {
                            bT++;
                        }
                        mantissa[ib++] = bT;
                        break;
                    }

                    // if (biNum < biHiLo || biNum == biHiLo && even)
                    if (w1 < 0 || 0 == w1 && 0 == (dblLo & 1)) {
                        // if (biNum + biHi > biDen)
                        if (w2 > 0) {
                            // Decide whether to round up.
                            biNum.ShiftLeft(1);
                            w2 = biNum.CompareTo(biDen);
                            if ((w2 > 0 || 0 == w2 && (0 != (bT & 1))) && bT++ == 9) {
                                goto LRoundUp9;
                            }
                        }
                        mantissa[ib++] = bT;
                        break;
                    }

                    // if (biNum + biHi > biDen)
                    if (w2 > 0) {
                        // Round up and be done with it.
                        if (bT != 9) {
                            mantissa[ib++] = (byte)(bT + 1);
                            break;
                        }
                        goto LRoundUp9;
                    }

                    // Save the digit.
                    mantissa[ib++] = bT;

            LSkip:
                    biNum.MulAdd(10, 0);
                    biHi.MulAdd(10, 0);
                    if ((object) biHiLo != (object) biHi) {
                        biHiLo.MulAdd(10, 0);
                    }
                    continue;

            LRoundUp9:
                    while (ib > 0) {
                        if (mantissa[--ib] != 9) {
                            mantissa[ib++]++;
                            goto LReturn;
                        }
                    }
                    wExp10++;
                    mantissa[ib++] = 1;
                    break;
                }

            LReturn:
                exponent = wExp10 + 1;
                mantissaSize = ib;
            }
        // D.1.4 91

        /**
         * return a sqrt root - the routine verifies that the calculation
         * returns the right value - if none exists it returns null.
         */
        public override ECFieldElement Sqrt()
        {
            if (!q.TestBit(0))
            {
                throw Platform.CreateNotImplementedException("even value of q");
            }

            // p mod 4 == 3
            if (q.TestBit(1))
            {
                // TODO Can this be optimised (inline the Square?)
                // z = g^(u+1) + p, p = 4u + 3
                ECFieldElement z = new FpFieldElement(q, x.ModPow(q.ShiftRight(2).Add(BigInteger.One), q));

                return(z.Square().Equals(this) ? z : null);
            }

            // p mod 4 == 1
            BigInteger qMinusOne = q.Subtract(BigInteger.One);

            BigInteger legendreExponent = qMinusOne.ShiftRight(1);

            if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
            {
                return(null);
            }

            BigInteger u = qMinusOne.ShiftRight(2);
            BigInteger k = u.ShiftLeft(1).Add(BigInteger.One);

            BigInteger Q     = this.x;
            BigInteger fourQ = Q.ShiftLeft(2).Mod(q);

            BigInteger U, V;

            do
            {
                Random     rand = new Random();
                BigInteger P;
                do
                {
                    P = new BigInteger(q.BitLength, rand);
                }while (P.CompareTo(q) >= 0 ||
                        !(P.Multiply(P).Subtract(fourQ).ModPow(legendreExponent, q).Equals(qMinusOne)));

                BigInteger[] result = fastLucasSequence(q, P, Q, k);
                U = result[0];
                V = result[1];

                if (V.Multiply(V).Mod(q).Equals(fourQ))
                {
                    // Integer division by 2, mod q
                    if (V.TestBit(0))
                    {
                        V = V.Add(q);
                    }

                    V = V.ShiftRight(1);

                    Debug.Assert(V.Multiply(V).Mod(q).Equals(x));

                    return(new FpFieldElement(q, V));
                }
            }while (U.Equals(BigInteger.One) || U.Equals(qMinusOne));

            return(null);


//			BigInteger qMinusOne = q.Subtract(BigInteger.One);
//
//			BigInteger legendreExponent = qMinusOne.ShiftRight(1);
//			if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
//				return null;
//
//			Random rand = new Random();
//			BigInteger fourX = x.ShiftLeft(2);
//
//			BigInteger r;
//			do
//			{
//				r = new BigInteger(q.BitLength, rand);
//			}
//			while (r.CompareTo(q) >= 0
//				|| !(r.Multiply(r).Subtract(fourX).ModPow(legendreExponent, q).Equals(qMinusOne)));
//
//			BigInteger n1 = qMinusOne.ShiftRight(2);
//			BigInteger n2 = n1.Add(BigInteger.One);
//
//			BigInteger wOne = WOne(r, x, q);
//			BigInteger wSum = W(n1, wOne, q).Add(W(n2, wOne, q)).Mod(q);
//			BigInteger twoR = r.ShiftLeft(1);
//
//			BigInteger root = twoR.ModPow(q.Subtract(BigInteger.Two), q)
//				.Multiply(x).Mod(q)
//				.Multiply(wSum).Mod(q);
//
//			return new FpFieldElement(q, root);
        }
Ejemplo n.º 31
0
        /// <summary>
        /// Get a pseudo random 64bit integer
        /// </summary>
        /// 
        /// <returns>Random Int64</returns>
        public Int64 NextLong()
        {
            // Xi+1 = (2Xi pow 2) + 3Xi + (1 mod P)
            _G = _G.Multiply(_G.Add(_G).Add(_BI3)).Add(BigInteger.One).Mod(_P);

            // set G to 2 if G <= 1
            if (_G.CompareTo(BigInteger.One) < 1)
                _G = BigInteger.ValueOf(2);

            return _G.ToInt64();
        }
Ejemplo n.º 32
0
 /// <summary>
 /// Compares token to the object
 /// </summary>
 public int CompareTo(object obj)
 {
     return(value.CompareTo(((Token)obj).value));
 }
Ejemplo n.º 33
0
        // Stratis kernel protocol
        // coinstake must meet hash target according to the protocol:
        // kernel (input 0) must meet the formula
        //     hash(nStakeModifier + txPrev.block.nTime + txPrev.nTime + txPrev.vout.hash + txPrev.vout.n + nTime) < bnTarget * nWeight
        // this ensures that the chance of getting a coinstake is proportional to the
        // amount of coins one owns.
        // The reason this hash is chosen is the following:
        //   nStakeModifier: scrambles computation to make it very difficult to precompute
        //                   future proof-of-stake
        //   txPrev.block.nTime: prevent nodes from guessing a good timestamp to
        //                       generate transaction for future advantage,
        //                       obsolete since v3
        //   txPrev.nTime: slightly scrambles computation
        //   txPrev.vout.hash: hash of txPrev, to reduce the chance of nodes
        //                     generating coinstake at the same time
        //   txPrev.vout.n: output number of txPrev, to reduce the chance of nodes
        //                  generating coinstake at the same time
        //   nTime: current timestamp
        //   block/tx hash should not be used here as they can be generated in vast
        //   quantities so as to generate blocks faster, degrading the system back into
        //   a proof-of-work situation.
        //
        private static bool CheckStakeKernelHashV2(ChainedBlock pindexPrev, uint nBits, uint nTimeBlockFrom,
                                                   Transaction txPrev, OutPoint prevout, uint nTimeTx, out uint256 hashProofOfStake, out uint256 targetProofOfStake, bool fPrintProofOfStake)
        {
            targetProofOfStake = null; hashProofOfStake = null;

            if (nTimeTx < txPrev.Time)        // Transaction timestamp violation
            {
                return(false);                //error("CheckStakeKernelHash() : nTime violation");
            }
            // Base target
            var bnTarget = new Target(nBits).ToBigInteger();

            // Weighted target
            var nValueIn = txPrev.Outputs[prevout.N].Value.Satoshi;
            var bnWeight = BigInteger.ValueOf(nValueIn);

            bnTarget = bnTarget.Multiply(bnWeight);

            // todo: investigate this issue, is the convertion to uint256 similar to the c++ implementation
            //targetProofOfStake = Target.ToUInt256(bnTarget);

            var     nStakeModifier       = pindexPrev.Header.PosParameters.StakeModifier;
            uint256 bnStakeModifierV2    = pindexPrev.Header.PosParameters.StakeModifierV2;
            int     nStakeModifierHeight = pindexPrev.Height;
            var     nStakeModifierTime   = pindexPrev.Header.Time;

            // Calculate hash
            using (var ms = new MemoryStream())
            {
                var serializer = new BitcoinStream(ms, true);
                if (IsProtocolV3((int)nTimeTx))
                {
                    serializer.ReadWrite(bnStakeModifierV2);
                }
                else
                {
                    serializer.ReadWrite(nStakeModifier);
                    serializer.ReadWrite(nTimeBlockFrom);
                }

                serializer.ReadWrite(txPrev.Time);
                serializer.ReadWrite(prevout.Hash);
                serializer.ReadWrite(prevout.N);
                serializer.ReadWrite(nTimeTx);

                hashProofOfStake = Hashes.Hash256(ms.ToArray());
            }

            if (fPrintProofOfStake)
            {
                //LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n",
                //	nStakeModifier, nStakeModifierHeight,
                //	DateTimeStrFormat(nStakeModifierTime),

                //	DateTimeStrFormat(nTimeBlockFrom));

                //LogPrintf("CheckStakeKernelHash() : check modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n",
                //	nStakeModifier,
                //	nTimeBlockFrom, txPrev.nTime, prevout.n, nTimeTx,
                //	hashProofOfStake.ToString());
            }

            // Now check if proof-of-stake hash meets target protocol
            var hashProofOfStakeTarget = new BigInteger(hashProofOfStake.ToBytes(false));

            if (hashProofOfStakeTarget.CompareTo(bnTarget) > 0)
            {
                return(false);
            }


            //  if (fDebug && !fPrintProofOfStake)
            //  {
            //		LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n",
            //		nStakeModifier, nStakeModifierHeight,
            //		DateTimeStrFormat(nStakeModifierTime),

            //		DateTimeStrFormat(nTimeBlockFrom));

            //		LogPrintf("CheckStakeKernelHash() : pass modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n",
            //		nStakeModifier,
            //		nTimeBlockFrom, txPrev.nTime, prevout.n, nTimeTx,
            //		hashProofOfStake.ToString());
            //  }

            return(true);
        }
Ejemplo n.º 34
0
        /**
         * Compute the pseudorandom k for signature generation,
         * using the process specified for deterministic DSA.
         *
         * @param h1   the hashed message
         * @return  the pseudorandom k to use
         */
        private BigInteger computek(byte[] h1)
        {
            /*
             * Convert hash value into an appropriately truncated
             * and/or expanded sequence of octets.  The private
             * key was already processed (into field bx[]).
             */
            byte[] bh = bits2octets(h1);

            /*
             * HMAC is always used with K as key.
             * Whenever K is updated, we reset the
             * current HMAC key.
             */

            /* step b. */
            byte[] V = new byte[holen];
            for (int i = 0; i < holen; i++)
            {
                V[i] = 0x01;
            }

            /* step c. */
            byte[] K = new byte[holen];
            setHmacKey(K);

            /* step d. */
            hmac.Update(V);
            hmac.Update((byte)0x00);

            hmac.Update(bx);
            hmac.Update(bh);
            K = hmac.DoFinal();
            setHmacKey(K);

            /* step e. */
            hmac.Update(V);
            V = hmac.DoFinal();

            /* step f. */
            hmac.Update(V);
            hmac.Update((byte)0x01);
            hmac.Update(bx);
            hmac.Update(bh);
            K = hmac.DoFinal();
            setHmacKey(K);

            /* step g. */
            hmac.Update(V);
            V = hmac.DoFinal();

            /* step h. */
            byte[] T = new byte[rolen];
            for ( ; ;)
            {
                /*
                 * We want qlen bits, but we support only
                 * hash functions with an output length
                 * multiple of 8;acd hence, we will gather
                 * rlen bits, i.e., rolen octets.
                 */
                int toff = 0;
                while (toff < rolen)
                {
                    hmac.Update(V);
                    V = hmac.DoFinal();
                    int cc = Math.Min(V.Length,
                                      T.Length - toff);
                    Array.Copy(V, 0, T, toff, cc);
                    toff += cc;
                }
                BigInteger k = bits2int(T);
                if (k.SignValue > 0 && k.CompareTo(q) < 0)
                {
                    return(k);
                }

                /*
                 * k is not in the proper range; update
                 * K and V, and loop.
                 */

                hmac.Update(V);
                hmac.Update((byte)0x00);
                K = hmac.DoFinal();
                setHmacKey(K);
                hmac.Update(V);
                V = hmac.DoFinal();
            }
        }
Ejemplo n.º 35
0
 public int CompareTo(Money other)
 {
     return(_Satoshis.CompareTo(other._Satoshis));
 }
Ejemplo n.º 36
0
        /// <summary>
        /// Get a pseudo random 64bit integer
        /// </summary>
        /// 
        /// <returns>Random Int64</returns>
        public Int64 NextLong()
        {
            // Xi+1 = (Xi pow 2) mod P
            _G = _G.Multiply(_G).Mod(_P);

            // set g to 2 if g <= 1.
            if (_G.CompareTo(BigInteger.One) < 1)
                _G = BigInteger.ValueOf(2);

            return _G.ToInt64();
        }
Ejemplo n.º 37
0
        public Key Derivate(byte[] cc, uint nChild, out byte[] ccChild)
        {
            AssertNotDisposed();
#if HAS_SPAN
            if (!IsCompressed)
            {
                throw new InvalidOperationException("The key must be compressed");
            }
            Span <byte> vout = stackalloc byte[64];
            vout.Clear();
            if ((nChild >> 31) == 0)
            {
                Span <byte> pubkey = stackalloc byte[33];
                this.PubKey.ToBytes(pubkey, out _);
                Hashes.BIP32Hash(cc, nChild, pubkey[0], pubkey.Slice(1), vout);
            }
            else
            {
                Span <byte> privkey = stackalloc byte[32];
                this._ECKey.WriteToSpan(privkey);
                Hashes.BIP32Hash(cc, nChild, 0, privkey, vout);
                privkey.Fill(0);
            }
            ccChild = new byte[32];
            vout.Slice(32, 32).CopyTo(ccChild);
            Secp256k1.ECPrivKey keyChild = _ECKey.TweakAdd(vout.Slice(0, 32));
            vout.Clear();
            return(new Key(keyChild, true));
#else
            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 has probability lower than 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));
#endif
        }
Ejemplo n.º 38
0
        public bool VerifySignature(byte[] data, string signature)
        {
            if (!signature.StartsWith(Signature.K1Prefix) && !signature.StartsWith(Signature.R1Prefix))
            {
                return(false);
            }

            byte[] buf = Base58.Decode(signature.Substring(Signature.PrefixLength));

            if (buf.Length != Signature.Length + ChecksumLength)
            {
                return(false);
            }

            byte[] signatureBuf = new byte[buf.Length - ChecksumLength];
            Array.Copy(buf, 0, signatureBuf, 0, Signature.Length);

            byte[] checksum;

            if (signature.StartsWith(Signature.R1Prefix))
            {
                checksum = RIPEMD160.ComputeHash(signatureBuf.Concat(R1Salt)).TakePart(0, 4);
            }
            else
            {
                checksum = RIPEMD160.ComputeHash(signatureBuf.Concat(K1Salt)).TakePart(0, 4);
            }

            if (!CheckChecksum(buf, checksum))
            {
                return(false);
            }

            byte[] hash;

            using (SHA256 sha = SHA256.Create())
            {
                hash = sha.ComputeHash(data, 0, data.Length);
            }

            byte       recoveryId = (byte)(signatureBuf[0] - 31);
            BigInteger r          = signatureBuf.ToInt256(1);
            BigInteger s          = signatureBuf.ToInt256(33);

            var q = RecoverPublicKey(hash, r, s, recoveryId, Curve);

            if (q.X.Value != Q.X.Value && q.Y.Value != Q.Y.Value)
            {
                return(false);
            }

            if (r.Sign < 1 || s.Sign < 1 || r.CompareTo(Curve.N) >= 0 || s.CompareTo(Curve.N) >= 0)
            {
                return(false);
            }

            BigInteger e  = hash.ToInt256();
            BigInteger c  = s.ModInverse(Curve.N);
            BigInteger u1 = (e * c).Mod(Curve.N);
            BigInteger u2 = (r * c).Mod(Curve.N);
            Point      R  = Curve.G.MultiplyTwo(u1, q, u2);
            BigInteger v  = R.X.Value.Mod(Curve.N);

            return(v.Equals(r));
        }
Ejemplo n.º 39
0
        /// <summary>
        /// Calculates the difficulty target for the next block.
        /// </summary>
        /// <param name="stakeChain">Database of stake related data for the current blockchain.</param>
        /// <param name="chainedBlock">Block header for which to calculate the target difficulty.</param>
        /// <param name="consensus">Consensus rules for the current network.</param>
        /// <param name="proofOfStake"><c>true</c> for calculation of PoS difficulty target, <c>false</c> for calculation of PoW difficulty target.</param>
        /// <returns>The difficulty target for the next block after <paramref name="chainedBlock"/>.</returns>
        /// <remarks>
        /// The calculation of the next target is based on the last target value and the block time (aka spacing) of <paramref name="chainedBlock"/>
        /// (i.e. difference in time stamp of this block and its immediate predecessor). The target changes every block and it is adjusted
        /// down (i.e. towards harder to reach, or more difficult) if the time to mine last block was lower than the target block time.
        /// And it is adjusted up if it took longer than the target block time. The adjustments are done in a way the target is moving towards
        /// the target spacing exponentially, so even a big change in the mining power on the network will be fixed by retargeting relatively quickly.
        /// <para>
        /// Over <see cref="RetargetIntervalMinutes"/> minutes there are certain number (say <c>N</c>) of blocks expected to be mined if the target block time
        /// of <see cref="TargetSpacingSeconds"/> was reached every time. Then the next target is calculated as follows:</para>
        /// <code>
        /// NewTarget = PrevTarget * ((N - 1) * TargetSpacingSeconds + 2 * LastBlockTime) / ((N + 1) * TargetSpacingSeconds)
        /// </code>
        /// <para>
        /// Which basically says that the block time of the last block is counted twice instead of two optimal block times.
        /// And the <c>N</c> determines how strongly will the deviation of the last block time affect the difficulty.
        /// </para>
        /// </remarks>
        public static Target GetNextTargetRequired(StakeChain stakeChain, ChainedBlock chainedBlock, NBitcoin.Consensus consensus, bool proofOfStake)
        {
            clogger.LogTrace("({0}:'{1}',{2}:{3})", nameof(chainedBlock), chainedBlock, nameof(proofOfStake), proofOfStake);

            // Genesis block.
            if (chainedBlock == null)
            {
                clogger.LogTrace("(-)[GENESIS]:'{0}'", consensus.PowLimit);
                return(consensus.PowLimit);
            }

            // Find the last two blocks that correspond to the mining algo
            // (i.e if this is a POS block we need to find the last two POS blocks).
            BigInteger targetLimit = proofOfStake
                ? consensus.ProofOfStakeLimitV2
                : consensus.PowLimit.ToBigInteger();

            // First block.
            ChainedBlock pindexPrev = GetLastBlockIndex(stakeChain, chainedBlock, proofOfStake);

            if (pindexPrev.Previous == null)
            {
                var res = new Target(targetLimit);
                clogger.LogTrace("(-)[FIRST_BLOCK]:'{0}'", res);
                return(res);
            }

            // Second block.
            ChainedBlock pindexPrevPrev = GetLastBlockIndex(stakeChain, pindexPrev.Previous, proofOfStake);

            if (pindexPrevPrev.Previous == null)
            {
                var res = new Target(targetLimit);
                clogger.LogTrace("(-)[SECOND_BLOCK]:'{0}'", res);
                return(res);
            }

            // This is used in tests to allow quickly mining blocks.
            if (consensus.PowNoRetargeting)
            {
                clogger.LogTrace("(-)[NO_POW_RETARGET]:'{0}'", pindexPrev.Header.Bits);
                return(pindexPrev.Header.Bits);
            }

            int targetSpacing = TargetSpacingSeconds;
            int actualSpacing = (int)(pindexPrev.Header.Time - pindexPrevPrev.Header.Time);

            if (actualSpacing < 0)
            {
                actualSpacing = targetSpacing;
            }

            if (actualSpacing > targetSpacing * 10)
            {
                actualSpacing = targetSpacing * 10;
            }

            int targetTimespan = RetargetIntervalMinutes * 60;
            int interval       = targetTimespan / targetSpacing;

            BigInteger target = pindexPrev.Header.Bits.ToBigInteger();

            long multiplyBy = (interval - 1) * targetSpacing + actualSpacing + actualSpacing;

            target = target.Multiply(BigInteger.ValueOf(multiplyBy));

            long divideBy = (interval + 1) * targetSpacing;

            target = target.Divide(BigInteger.ValueOf(divideBy));

            clogger.LogTrace("The next target difficulty will be {0} times higher (easier to satisfy) than the previous target.", (double)multiplyBy / (double)divideBy);

            if ((target.CompareTo(BigInteger.Zero) <= 0) || (target.CompareTo(targetLimit) >= 1))
            {
                target = targetLimit;
            }

            var finalTarget = new Target(target);

            clogger.LogTrace("(-):'{0}'", finalTarget);
            return(finalTarget);
        }
Ejemplo n.º 40
0
        /// <summary>
        /// Verifying algorithm as specified in section 2.6.3 of the setup
        /// </summary>
        /// <param name="pubKey">Public Key used to verify the proof</param>
        /// <param name="proof">Proof</param>
        /// <param name="setup">Setup parameters</param>
        /// <returns> true if the signatures verify, false otherwise</returns>
        public static bool VerifyPermutationTest(this RsaKeyParameters pubKey, PermutationTestProof proof, PermutationTestSetup setup)
        {
            if (setup == null)
            {
                throw new ArgumentNullException(nameof(setup));
            }
            if (proof == null)
            {
                throw new ArgumentNullException(nameof(proof));
            }

            byte[][] sigs      = proof.Signatures;
            int      alpha     = setup.Alpha;
            int      keyLength = setup.KeySize;

            byte[] psBytes = setup.PublicString;
            int    k       = setup.SecurityParameter;

            BigInteger Modulus  = pubKey.Modulus;
            BigInteger Exponent = pubKey.Exponent;

            BigInteger Two = BigInteger.Two;
            // 2^{|N| - 1}
            BigInteger lowerLimit = Two.Pow(keyLength - 1);
            // 2^{|N|}
            BigInteger upperLimit = Two.Pow(keyLength);

            // if N < 2^{KeySize-1}
            if (Modulus.CompareTo(lowerLimit) < 0)
            {
                return(false);
            }

            // if N >= 2^{KeySize}
            if (Modulus.CompareTo(upperLimit) >= 0)
            {
                return(false);
            }

            // Generate m1 and m2
            Get_m1_m2((decimal)alpha, Exponent.IntValue, k, out int m1, out int m2);

            // Verifying m2
            if (!m2.Equals(sigs.Length))
            {
                return(false);
            }

            // Verify alpha and N
            if (!CheckAlphaN(alpha, Modulus))
            {
                return(false);
            }

            // Generate a "weird" public key
            var eN          = Modulus.Multiply(Exponent);
            var pubKeyPrime = new RsaKeyParameters(false, Modulus, eN);

            // Generate list of rho values
            GetRhos(m2, psBytes, pubKey, keyLength, out byte[][] rhoValues);

            // Verifying the signatures
            for (int i = 0; i < m2; i++)
            {
                if (i <= m1)
                {
                    var dec_sig = pubKeyPrime.Encrypt(sigs[i]);
                    if (!dec_sig.SequenceEqual(rhoValues[i]))
                    {
                        return(false);
                    }
                }
                else
                {
                    var dec_sig = pubKey.Encrypt(sigs[i]);
                    if (!dec_sig.SequenceEqual(rhoValues[i]))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Ejemplo n.º 41
0
        /// <summary>
        /// Encode a number between 0 and (n|t) (binomial coefficient) into a binary vector of length n with weight t. 
        /// <para>The number is given as a byte array. Only the first s bits are used, where s = floor[log(n|t)].</para>
        /// </summary>
        /// 
        /// <param name="N">The "n" integer</param>
        /// <param name="T">The "t" integer</param>
        /// <param name="M">The message as a byte array</param>
        /// 
        /// <returns>The encoded message as GF2Vector</returns>
        public static GF2Vector Encode(int N, int T, byte[] M)
        {
            if (N < T)
                throw new ArgumentException("n < t");

            // compute the binomial c = (n|t)
            BigInteger c = BigMath.Binomial(N, T);
            // get the number encoded in m
            BigInteger i = new BigInteger(1, M);
            // compare
            if (i.CompareTo(c) >= 0)
                throw new ArgumentException("Encoded number too large.");

            GF2Vector result = new GF2Vector(N);
            int nn = N;
            int tt = T;

            for (int j = 0; j < N; j++)
            {
                c = c.Multiply(BigInteger.ValueOf(nn - tt)).Divide(BigInteger.ValueOf(nn));
                nn--;

                if (c.CompareTo(i) <= 0)
                {
                    result.SetBit(j);
                    i = i.Subtract(c);
                    tt--;

                    if (nn == tt)
                        c = ONE;
                    else
                        c = (c.Multiply(BigInteger.ValueOf(tt + 1))).Divide(BigInteger.ValueOf(nn - tt));
                }
            }

            return result;
        }
Ejemplo n.º 42
0
        public virtual bool Match(
            object obj)
        {
            X509Crl c = obj as X509Crl;

            if (c == null)
            {
                return(false);
            }

            if (dateAndTime != null)
            {
                DateTime       dt = dateAndTime.Value;
                DateTime       tu = c.ThisUpdate;
                DateTimeObject nu = c.NextUpdate;

                if (dt.CompareTo(tu) < 0 || nu == null || dt.CompareTo(nu.Value) >= 0)
                {
                    return(false);
                }
            }

            if (issuers != null)
            {
                X509Name i = c.IssuerDN;

                bool found = false;

                foreach (X509Name issuer in issuers)
                {
                    if (issuer.Equivalent(i, true))
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    return(false);
                }
            }

            if (maxCrlNumber != null || minCrlNumber != null)
            {
                Asn1OctetString extVal = c.GetExtensionValue(X509Extensions.CrlNumber);
                if (extVal == null)
                {
                    return(false);
                }

                BigInteger cn = CrlNumber.GetInstance(
                    X509ExtensionUtilities.FromExtensionValue(extVal)).PositiveValue;

                if (maxCrlNumber != null && cn.CompareTo(maxCrlNumber) > 0)
                {
                    return(false);
                }

                if (minCrlNumber != null && cn.CompareTo(minCrlNumber) < 0)
                {
                    return(false);
                }
            }

            DerInteger dci = null;

            try
            {
                Asn1OctetString bytes = c.GetExtensionValue(X509Extensions.DeltaCrlIndicator);
                if (bytes != null)
                {
                    dci = DerInteger.GetInstance(X509ExtensionUtilities.FromExtensionValue(bytes));
                }
            }
            catch (Exception)
            {
                return(false);
            }

            if (dci == null)
            {
                if (DeltaCrlIndicatorEnabled)
                {
                    return(false);
                }
            }
            else
            {
                if (CompleteCrlEnabled)
                {
                    return(false);
                }

                if (maxBaseCrlNumber != null && dci.PositiveValue.CompareTo(maxBaseCrlNumber) > 0)
                {
                    return(false);
                }
            }

            if (issuingDistributionPointEnabled)
            {
                Asn1OctetString idp = c.GetExtensionValue(X509Extensions.IssuingDistributionPoint);
                if (issuingDistributionPoint == null)
                {
                    if (idp != null)
                    {
                        return(false);
                    }
                }
                else
                {
                    if (!Arrays.AreEqual(idp.GetOctets(), issuingDistributionPoint))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Ejemplo n.º 43
0
		// D.1.4 91
		/**
		 * return a sqrt root - the routine verifies that the calculation
		 * returns the right value - if none exists it returns null.
		 */
		public override ECFieldElement Sqrt()
		{
			if (!q.TestBit(0))
				throw Platform.CreateNotImplementedException("even value of q");

			// p mod 4 == 3
			if (q.TestBit(1))
			{
				// TODO Can this be optimised (inline the Square?)
				// z = g^(u+1) + p, p = 4u + 3
				ECFieldElement z = new FpFieldElement(q, x.ModPow(q.ShiftRight(2).Add(BigInteger.One), q));

                return this.Equals(z.Square()) ? z : null;
			}

			// p mod 4 == 1
			BigInteger qMinusOne = q.Subtract(BigInteger.One);

			BigInteger legendreExponent = qMinusOne.ShiftRight(1);
			if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
				return null;

			BigInteger u = qMinusOne.ShiftRight(2);
			BigInteger k = u.ShiftLeft(1).Add(BigInteger.One);

			BigInteger Q = this.x;
			BigInteger fourQ = Q.ShiftLeft(2).Mod(q);

			BigInteger U, V;
			do
			{
				Random rand = new Random();
				BigInteger P;
				do
				{
					P = new BigInteger(q.BitLength, rand);
				}
				while (P.CompareTo(q) >= 0
					|| !(P.Multiply(P).Subtract(fourQ).ModPow(legendreExponent, q).Equals(qMinusOne)));

				BigInteger[] result = fastLucasSequence(q, P, Q, k);
				U = result[0];
				V = result[1];

				if (V.Multiply(V).Mod(q).Equals(fourQ))
				{
					// Integer division by 2, mod q
					if (V.TestBit(0))
					{
						V = V.Add(q);
					}

					V = V.ShiftRight(1);

					Debug.Assert(V.Multiply(V).Mod(q).Equals(x));

					return new FpFieldElement(q, V);
				}
			}
			while (U.Equals(BigInteger.One) || U.Equals(qMinusOne));

			return null;


//			BigInteger qMinusOne = q.Subtract(BigInteger.One);
//
//			BigInteger legendreExponent = qMinusOne.ShiftRight(1);
//			if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
//				return null;
//
//			Random rand = new Random();
//			BigInteger fourX = x.ShiftLeft(2);
//
//			BigInteger r;
//			do
//			{
//				r = new BigInteger(q.BitLength, rand);
//			}
//			while (r.CompareTo(q) >= 0
//				|| !(r.Multiply(r).Subtract(fourX).ModPow(legendreExponent, q).Equals(qMinusOne)));
//
//			BigInteger n1 = qMinusOne.ShiftRight(2);
//			BigInteger n2 = n1.Add(BigInteger.One);
//
//			BigInteger wOne = WOne(r, x, q);
//			BigInteger wSum = W(n1, wOne, q).Add(W(n2, wOne, q)).Mod(q);
//			BigInteger twoR = r.ShiftLeft(1);
//
//			BigInteger root = twoR.ModPow(q.Subtract(BigInteger.Two), q)
//				.Multiply(x).Mod(q)
//				.Multiply(wSum).Mod(q);
//
//			return new FpFieldElement(q, root);
		}
        public virtual AsymmetricCipherKeyPair GenerateKeyPair()
        {
            for (;;)
            {
                //
                // p and q values should have a length of half the strength in bits
                //
                int strength    = parameters.Strength;
                int pBitlength  = (strength + 1) / 2;
                int qBitlength  = strength - pBitlength;
                int mindiffbits = strength / 3;
                int minWeight   = strength >> 2;

                BigInteger e = parameters.PublicExponent;

                // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes)
                // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm")

                BigInteger p = ChooseRandomPrime(pBitlength, e);
                BigInteger q, n;

                //
                // generate a modulus of the required length
                //
                for (;;)
                {
                    q = ChooseRandomPrime(qBitlength, e);

                    // p and q should not be too close together (or equal!)
                    BigInteger diff = q.Subtract(p).Abs();
                    if (diff.BitLength < mindiffbits)
                    {
                        continue;
                    }

                    //
                    // calculate the modulus
                    //
                    n = p.Multiply(q);

                    if (n.BitLength != strength)
                    {
                        //
                        // if we get here our primes aren't big enough, make the largest
                        // of the two p and try again
                        //
                        p = p.Max(q);
                        continue;
                    }

                    /*
                     * Require a minimum weight of the NAF representation, since low-weight composites may
                     * be weak against a version of the number-field-sieve for factoring.
                     *
                     * See "The number field sieve for integers of low weight", Oliver Schirokauer.
                     */
                    if (WNafUtilities.GetNafWeight(n) < minWeight)
                    {
                        p = ChooseRandomPrime(pBitlength, e);
                        continue;
                    }

                    break;
                }

                if (p.CompareTo(q) < 0)
                {
                    BigInteger tmp = p;
                    p = q;
                    q = tmp;
                }

                BigInteger pSub1 = p.Subtract(One);
                BigInteger qSub1 = q.Subtract(One);
                //BigInteger phi = pSub1.Multiply(qSub1);
                BigInteger gcd = pSub1.Gcd(qSub1);
                BigInteger lcm = pSub1.Divide(gcd).Multiply(qSub1);

                //
                // calculate the private exponent
                //
                BigInteger d = e.ModInverse(lcm);

                if (d.BitLength <= qBitlength)
                {
                    continue;
                }

                //
                // calculate the CRT factors
                //
                BigInteger dP   = d.Remainder(pSub1);
                BigInteger dQ   = d.Remainder(qSub1);
                BigInteger qInv = BigIntegers.ModOddInverse(p, q);

                return(new AsymmetricCipherKeyPair(
                           new RsaKeyParameters(false, n, e),
                           new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv)));
            }
        }
Ejemplo n.º 45
0
        internal FpFieldElement(BigInteger q, BigInteger r, BigInteger x)
        {
            if (x == null || x.SignValue < 0 || x.CompareTo(q) >= 0)
                throw new ArgumentException("value invalid in Fp field element", "x");

            this.q = q;
            this.r = r;
            this.x = x;
        }
Ejemplo n.º 46
0
        public static bool CheckIsCanonical(byte[] sig, bool strict)
        {
            // Make sure signature is canonical
            // To protect against signature morphing attacks

            // Signature should be:
            // <30> <len> [ <02> <lenR> <R> ] [ <02> <lenS> <S> ]
            // where
            // 6 <= len <= 70
            // 1 <= lenR <= 33
            // 1 <= lenS <= 33

            int sigLen = sig.Length;

            if ((sigLen < 8) || (sigLen > 72))
            {
                return(false);
            }

            if ((sig[0] != 0x30) || (sig[1] != (sigLen - 2)))
            {
                return(false);
            }

            // Find R and check its length
            int rPos = 4, rLen = sig[rPos - 1];

            if ((rLen < 1) || (rLen > 33) || ((rLen + 7) > sigLen))
            {
                return(false);
            }

            // Find S and check its length
            int sPos = rLen + 6, sLen = sig[sPos - 1];

            if ((sLen < 1) || (sLen > 33) || ((rLen + sLen + 6) != sigLen))
            {
                return(false);
            }

            if ((sig[rPos - 2] != 0x02) || (sig[sPos - 2] != 0x02))
            {
                return(false); // R or S have wrong type
            }

            if ((sig[rPos] & 0x80) != 0)
            {
                return(false); // R is negative
            }

            if ((sig[rPos] == 0) && rLen == 1)
            {
                return(false); // R is zero
            }

            if ((sig[rPos] == 0) && ((sig[rPos + 1] & 0x80) == 0))
            {
                return(false); // R is padded
            }

            if ((sig[sPos] & 0x80) != 0)
            {
                return(false); // S is negative
            }

            if ((sig[sPos] == 0) && sLen == 1)
            {
                return(false); // S is zero
            }

            if ((sig[sPos] == 0) && ((sig[sPos + 1] & 0x80) == 0))
            {
                return(false); // S is padded
            }

            byte[] rBytes = new byte[rLen];
            byte[] bytes  = new byte[sLen];

            Array.Copy(sig, rPos, rBytes, 0, rLen);
            Array.Copy(sig, sPos, bytes, 0, sLen);

            BigInteger r = new BigInteger(1, rBytes), s = new BigInteger(1, bytes);

            BigInteger order = Secp256K1.Order();

            if (r.CompareTo(order) != -1 || s.CompareTo(order) != -1)
            {
                return(false); // R or S greater than modulus
            }

            if (strict)
            {
                return(order.Subtract(s).CompareTo(s) != -1);
            }
            else
            {
                return(true);
            }
        }
Ejemplo n.º 47
0
 protected virtual BigInteger ModReduce(BigInteger x)
 {
     if (r == null)
     {
         x = x.Mod(q);
     }
     else
     {
         bool negative = x.SignValue < 0;
         if (negative)
         {
             x = x.Abs();
         }
         int qLen = q.BitLength;
         if (r.SignValue > 0)
         {
             BigInteger qMod = BigInteger.One.ShiftLeft(qLen);
             bool rIsOne = r.Equals(BigInteger.One);
             while (x.BitLength > (qLen + 1))
             {
                 BigInteger u = x.ShiftRight(qLen);
                 BigInteger v = x.Remainder(qMod);
                 if (!rIsOne)
                 {
                     u = u.Multiply(r);
                 }
                 x = u.Add(v);
             }
         }
         else
         {
             int d = ((qLen - 1) & 31) + 1;
             BigInteger mu = r.Negate();
             BigInteger u = mu.Multiply(x.ShiftRight(qLen - d));
             BigInteger quot = u.ShiftRight(qLen + d);
             BigInteger v = quot.Multiply(q);
             BigInteger bk1 = BigInteger.One.ShiftLeft(qLen + d);
             v = v.Remainder(bk1);
             x = x.Remainder(bk1);
             x = x.Subtract(v);
             if (x.SignValue < 0)
             {
                 x = x.Add(bk1);
             }
         }
         while (x.CompareTo(q) >= 0)
         {
             x = x.Subtract(q);
         }
         if (negative && x.SignValue != 0)
         {
             x = q.Subtract(x);
         }
     }
     return x;
 }
Ejemplo n.º 48
0
        /**
         * Computes the <code>[&#964;]</code>-adic window NAF of an element
         * <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>.
         * @param mu The parameter &#956; of the elliptic curve.
         * @param lambda The element <code>&#955;</code> of
         * <code><b>Z</b>[&#964;]</code> of which to compute the
         * <code>[&#964;]</code>-adic NAF.
         * @param width The window width of the resulting WNAF.
         * @param pow2w 2<sup>width</sup>.
         * @param tw The auxiliary value <code>t<sub>w</sub></code>.
         * @param alpha The <code>&#945;<sub>u</sub></code>'s for the window width.
         * @return The <code>[&#964;]</code>-adic window NAF of
         * <code>&#955;</code>.
         */
        public static sbyte[] TauAdicWNaf(sbyte mu, ZTauElement lambda,
                                          sbyte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha)
        {
            if (!((mu == 1) || (mu == -1)))
            {
                throw new ArgumentException("mu must be 1 or -1");
            }

            BigInteger norm = Norm(mu, lambda);

            // Ceiling of log2 of the norm
            int log2Norm = norm.BitLength;

            // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52
            int maxLength = log2Norm > 30 ? log2Norm + 4 + width : 34 + width;

            // The array holding the TNAF
            var u = new sbyte[maxLength];

            // 2^(width - 1)
            BigInteger pow2wMin1 = pow2w.ShiftRight(1);

            // Split lambda into two BigIntegers to simplify calculations
            BigInteger r0 = lambda.u;
            BigInteger r1 = lambda.v;
            int        i  = 0;

            // while lambda <> (0, 0)
            while (!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero))))
            {
                // if r0 is odd
                if (r0.TestBit(0))
                {
                    // uUnMod = r0 + r1*tw Mod 2^width
                    BigInteger uUnMod
                        = r0.Add(r1.Multiply(tw)).Mod(pow2w);

                    sbyte uLocal;
                    // if uUnMod >= 2^(width - 1)
                    if (uUnMod.CompareTo(pow2wMin1) >= 0)
                    {
                        uLocal = (sbyte)uUnMod.Subtract(pow2w).IntValue;
                    }
                    else
                    {
                        uLocal = (sbyte)uUnMod.IntValue;
                    }
                    // uLocal is now in [-2^(width-1), 2^(width-1)-1]

                    u[i] = uLocal;
                    bool s = true;
                    if (uLocal < 0)
                    {
                        s      = false;
                        uLocal = (sbyte)-uLocal;
                    }
                    // uLocal is now >= 0

                    if (s)
                    {
                        r0 = r0.Subtract(alpha[uLocal].u);
                        r1 = r1.Subtract(alpha[uLocal].v);
                    }
                    else
                    {
                        r0 = r0.Add(alpha[uLocal].u);
                        r1 = r1.Add(alpha[uLocal].v);
                    }
                }
                else
                {
                    u[i] = 0;
                }

                BigInteger t = r0;

                if (mu == 1)
                {
                    r0 = r1.Add(r0.ShiftRight(1));
                }
                else
                {
                    // mu == -1
                    r0 = r1.Subtract(r0.ShiftRight(1));
                }
                r1 = t.ShiftRight(1).Negate();
                i++;
            }
            return(u);
        }
Ejemplo n.º 49
0
        /// <summary>
        /// Computes the square root of a BigInteger modulo a prime employing the Shanks-Tonelli algorithm
        /// </summary>
        /// 
        /// <param name="X">The value out of which we extract the square root</param>
        /// <param name="P">The prime modulus that determines the underlying field</param>
        /// 
        /// <returns>Returns a number <c>B</c> such that B^2 = A (mod P) if <c>A</c> is a quadratic residue modulo <c>P</c></returns>
        public static BigInteger Ressol(BigInteger X, BigInteger P)
        {
            BigInteger v = null;

            if (X.CompareTo(ZERO) < 0)
                X = X.Add(P);
            if (X.Equals(ZERO))
                return ZERO;
            if (P.Equals(TWO))
                return X;

            // p = 3 mod 4
            if (P.TestBit(0) && P.TestBit(1))
            {
                if (Jacobi(X, P) == 1)
                {
                    // a quadr. residue mod p
                    v = P.Add(ONE); // v = p+1
                    v = v.ShiftRight(2); // v = v/4
                    return X.ModPow(v, P); // return a^v mod p
                }
                throw new ArgumentException("No quadratic residue: " + X + ", " + P);
            }

            long t = 0;

            // initialization
            // compute k and s, where p = 2^s (2k+1) +1

            BigInteger k = P.Subtract(ONE); // k = p-1
            long s = 0;
            while (!k.TestBit(0))
            { // while k is even
                s++; // s = s+1
                k = k.ShiftRight(1); // k = k/2
            }

            k = k.Subtract(ONE); // k = k - 1
            k = k.ShiftRight(1); // k = k/2

            // initial values
            BigInteger r = X.ModPow(k, P); // r = a^k mod p

            BigInteger n = r.Multiply(r).Remainder(P); // n = r^2 % p
            n = n.Multiply(X).Remainder(P); // n = n * a % p
            r = r.Multiply(X).Remainder(P); // r = r * a %p

            if (n.Equals(ONE))
            {
                return r;
            }

            // non-quadratic residue
            BigInteger z = TWO; // z = 2
            while (Jacobi(z, P) == 1)
            {
                // while z quadratic residue
                z = z.Add(ONE); // z = z + 1
            }

            v = k;
            v = v.Multiply(TWO); // v = 2k
            v = v.Add(ONE); // v = 2k + 1
            BigInteger c = z.ModPow(v, P); // c = z^v mod p

            // iteration
            while (n.CompareTo(ONE) == 1)
            { // n > 1
                k = n; // k = n
                t = s; // t = s
                s = 0;

                while (!k.Equals(ONE))
                { // k != 1
                    k = k.Multiply(k).Mod(P); // k = k^2 % p
                    s++; // s = s + 1
                }

                t -= s; // t = t - s
                if (t == 0)
                {
                    throw new ArgumentException("No quadratic residue: " + X + ", " + P);
                }

                v = ONE;
                for (long i = 0; i < t - 1; i++)
                {
                    v = v.ShiftLeft(1); // v = 1 * 2^(t - 1)
                }
                c = c.ModPow(v, P); // c = c^v mod p
                r = r.Multiply(c).Remainder(P); // r = r * c % p
                c = c.Multiply(c).Remainder(P); // c = c^2 % p
                n = n.Multiply(c).Mod(P); // n = n * c % p
            }
            return r;
        }
Ejemplo n.º 50
0
 public int CompareTo(SimpleBigDecimal val)
 {
     CheckScale(val);
     return(bigInt.CompareTo(val.bigInt));
 }
Ejemplo n.º 51
0
        /// <summary>
        /// Computes the value of the Jacobi symbol (A|B). 
        /// </summary>
        /// 
        /// <param name="A">The integer value</param>
        /// <param name="B">The integer value</param>
        /// 
        /// <returns>Returns value of the jacobi symbol (A|B)</returns>
        public static int Jacobi(BigInteger A, BigInteger B)
        {
            BigInteger a, b, v;
            long k = 1;

            // test trivial cases
            if (B.Equals(ZERO))
            {
                a = A.Abs();
                return a.Equals(ONE) ? 1 : 0;
            }

            if (!A.TestBit(0) && !B.TestBit(0))
                return 0;

            a = A;
            b = B;

            if (b.Signum() == -1)
            { // b < 0
                b = b.Negate();
                if (a.Signum() == -1)
                    k = -1;
            }

            v = ZERO;
            while (!b.TestBit(0))
            {
                v = v.Add(ONE);
                b = b.Divide(TWO);
            }

            if (v.TestBit(0))
                k = k * _jacobiTable[a.ToInt32() & 7];

            if (a.Signum() < 0)
            {
                if (b.TestBit(1))
                    k = -k;
                a = a.Negate();
            }

            // main loop
            while (a.Signum() != 0)
            {
                v = ZERO;
                while (!a.TestBit(0))
                { // a is even
                    v = v.Add(ONE);
                    a = a.Divide(TWO);
                }
                if (v.TestBit(0))
                    k = k * _jacobiTable[b.ToInt32() & 7];

                if (a.CompareTo(b) < 0)
                {
                    // swap and correct intermediate result
                    BigInteger x = a;
                    a = b;
                    b = x;
                    if (a.TestBit(1) && b.TestBit(1))
                        k = -k;
                }
                a = a.Subtract(b);
            }

            return b.Equals(ONE) ? (int)k : 0;
        }
Ejemplo n.º 52
0
 public override bool IsValidFieldElement(BigInteger x)
 {
     return(x != null && x.SignValue >= 0 && x.CompareTo(Field.Characteristic) < 0);
 }
Ejemplo n.º 53
0
        private static void VerifyComparison(BigInteger x, UInt64 y, int expectedResult)
        {
            bool expectedEquals = 0 == expectedResult;
            bool expectedLessThan = expectedResult < 0;
            bool expectedGreaterThan = expectedResult > 0;

            Assert.Equal(expectedEquals, x == y);
            Assert.Equal(expectedEquals, y == x);

            Assert.Equal(!expectedEquals, x != y);
            Assert.Equal(!expectedEquals, y != x);

            Assert.Equal(expectedEquals, x.Equals(y));

            VerifyCompareResult(expectedResult, x.CompareTo(y), "x.CompareTo(y)");

            if (expectedEquals)
            {
                Assert.Equal(x.GetHashCode(), ((BigInteger)y).GetHashCode());
                Assert.Equal(x.ToString(), ((BigInteger)y).ToString());
            }

            Assert.Equal(x.GetHashCode(), x.GetHashCode());
            Assert.Equal(((BigInteger)y).GetHashCode(), ((BigInteger)y).GetHashCode());

            Assert.Equal(expectedLessThan, x < y);
            Assert.Equal(expectedGreaterThan, y < x);

            Assert.Equal(expectedGreaterThan, x > y);
            Assert.Equal(expectedLessThan, y > x);

            Assert.Equal(expectedLessThan || expectedEquals, x <= y);
            Assert.Equal(expectedGreaterThan || expectedEquals, y <= x);

            Assert.Equal(expectedGreaterThan || expectedEquals, x >= y);
            Assert.Equal(expectedLessThan || expectedEquals, y >= x);
        }
Ejemplo n.º 54
0
    public static MROutput EnhancedMRProbablePrimeTest(BigInteger candidate, SecureRandom random, int iterations)
    {
        CheckCandidate(candidate, "candidate");
        if (random == null)
        {
            throw new ArgumentNullException("random");
        }
        if (iterations < 1)
        {
            throw new ArgumentException("must be > 0", "iterations");
        }
        if (candidate.BitLength == 2)
        {
            return(MROutput.ProbablyPrime());
        }
        if (!candidate.TestBit(0))
        {
            return(MROutput.ProvablyCompositeWithFactor(Two));
        }
        BigInteger bigInteger   = candidate.Subtract(One);
        BigInteger max          = candidate.Subtract(Two);
        int        lowestSetBit = bigInteger.GetLowestSetBit();
        BigInteger e            = bigInteger.ShiftRight(lowestSetBit);

        for (int i = 0; i < iterations; i++)
        {
            BigInteger bigInteger2 = BigIntegers.CreateRandomInRange(Two, max, random);
            BigInteger bigInteger3 = bigInteger2.Gcd(candidate);
            if (bigInteger3.CompareTo(One) > 0)
            {
                return(MROutput.ProvablyCompositeWithFactor(bigInteger3));
            }
            BigInteger bigInteger4 = bigInteger2.ModPow(e, candidate);
            if (bigInteger4.Equals(One) || bigInteger4.Equals(bigInteger))
            {
                continue;
            }
            bool       flag        = false;
            BigInteger bigInteger5 = bigInteger4;
            for (int j = 1; j < lowestSetBit; j++)
            {
                bigInteger4 = bigInteger4.ModPow(Two, candidate);
                if (bigInteger4.Equals(bigInteger))
                {
                    flag = true;
                    break;
                }
                if (bigInteger4.Equals(One))
                {
                    break;
                }
                bigInteger5 = bigInteger4;
            }
            if (flag)
            {
                continue;
            }
            if (!bigInteger4.Equals(One))
            {
                bigInteger5 = bigInteger4;
                bigInteger4 = bigInteger4.ModPow(Two, candidate);
                if (!bigInteger4.Equals(One))
                {
                    bigInteger5 = bigInteger4;
                }
            }
            bigInteger3 = bigInteger5.Subtract(One).Gcd(candidate);
            if (bigInteger3.CompareTo(One) > 0)
            {
                return(MROutput.ProvablyCompositeWithFactor(bigInteger3));
            }
            return(MROutput.ProvablyCompositeNotPrimePower());
        }
        return(MROutput.ProbablyPrime());
    }
Ejemplo n.º 55
0
        /**
         * The Miller-Rabin primality test.
         *
         * @param n the input number to be tested.
         * @param t the number of trials.
         * @return {@code false} if the number is definitely compose, otherwise
         *         {@code true} with probability {@code 1 - 4<sup>(-t)</sup>}.
         * @ar.org.fitc.ref "D. Knuth, The Art of Computer Programming Vo.2, Section
         *                  4.5.4., Algorithm P"
         */
        private static bool MillerRabin(BigInteger n, int t)
        {
            // PRE: n >= 0, t >= 0
            BigInteger x; // x := UNIFORM{2...n-1}
            BigInteger y; // y := x^(q * 2^j) mod n
            BigInteger n_minus_1 = n.Subtract(BigInteger.One); // n-1
            int bitLength = n_minus_1.BitLength; // ~ log2(n-1)
            // (q,k) such that: n-1 = q * 2^k and q is odd
            int k = n_minus_1.LowestSetBit;
            BigInteger q = n_minus_1.ShiftRight(k);
            Random rnd = new Random();

            for (int i = 0; i < t; i++) {
                // To generate a witness 'x', first it use the primes of table
                if (i < primes.Length) {
                    x = BIprimes[i];
                } else {/*
                     * It generates random witness only if it's necesssary. Note
                     * that all methods would call Miller-Rabin with t <= 50 so
                     * this part is only to do more robust the algorithm
                     */
                    do {
                        x = new BigInteger(bitLength, rnd);
                    } while ((x.CompareTo(n) >= BigInteger.EQUALS) || (x.Sign == 0)
                            || x.IsOne);
                }
                y = x.ModPow(q, n);
                if (y.IsOne || y.Equals(n_minus_1)) {
                    continue;
                }
                for (int j = 1; j < k; j++) {
                    if (y.Equals(n_minus_1)) {
                        continue;
                    }
                    y = y.Multiply(y).Mod(n);
                    if (y.IsOne) {
                        return false;
                    }
                }
                if (!y.Equals(n_minus_1)) {
                    return false;
                }
            }
            return true;
        }
Ejemplo n.º 56
0
        public DHParameters(
            BigInteger p,
            BigInteger g,
            BigInteger q,
            int m,
            int l,
            BigInteger j,
            DHValidationParameters validation)
        {
            if (p == null)
            {
                throw new ArgumentNullException("p");
            }
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }
            if (!p.TestBit(0))
            {
                throw new ArgumentException("field must be an odd prime", "p");
            }
            if (g.CompareTo(BigInteger.Two) < 0 ||
                g.CompareTo(p.Subtract(BigInteger.Two)) > 0)
            {
                throw new ArgumentException("generator must in the range [2, p - 2]", "g");
            }
            if (q != null && q.BitLength >= p.BitLength)
            {
                throw new ArgumentException("q too big to be a factor of (p-1)", "q");
            }
            if (m >= p.BitLength)
            {
                throw new ArgumentException("m value must be < bitlength of p", "m");
            }
            if (l != 0)
            {
                // TODO Check this against the Java version, which has 'l > p.BitLength' here
                if (l >= p.BitLength)
                {
                    throw new ArgumentException("when l value specified, it must be less than bitlength(p)", "l");
                }
                if (l < m)
                {
                    throw new ArgumentException("when l value specified, it may not be less than m value", "l");
                }
            }
            if (j != null && j.CompareTo(BigInteger.Two) < 0)
            {
                throw new ArgumentException("subgroup factor must be >= 2", "j");
            }

            // TODO If q, j both provided, validate p = jq + 1 ?

            this.p          = p;
            this.g          = g;
            this.q          = q;
            this.m          = m;
            this.l          = l;
            this.j          = j;
            this.validation = validation;
        }
Ejemplo n.º 57
0
        private void Initialize(int BitLength)
        {
            _P = BigInteger.ProbablePrime(BitLength, _secRand);
            _G = BigInteger.ProbablePrime(BitLength, _secRand);

            // if G >= P swap(G, P)
            if (_G.CompareTo(_P) > -1)
            {
                BigInteger temp = _G;
                _G = _P;
                _P = temp;
            }

            _G0 = _G;
        }
Ejemplo n.º 58
0
        /// <summary>
        /// Calculates x.modInverse(p) Based on: Savas, E; Koc, C "The Montgomery Modular Inverse - Revised"
        /// </summary>
        ///
        /// <param name="X">BigInteger X</param>
        /// <param name="P">BigInteger P</param>
        ///
        /// <returns>Returns <c>1/X Mod M</c></returns>
        internal static BigInteger ModInverseMontgomery(BigInteger X, BigInteger P)
        {
            // ZERO hasn't inverse
            if (X._sign == 0)
            {
                throw new ArithmeticException("BigInteger not invertible!");
            }

            // montgomery inverse require even modulo
            if (!P.TestBit(0))
            {
                return(ModInverseLorencz(X, P));
            }

            int m = P._numberLength * 32;
            // PRE: a \in [1, p - 1]
            BigInteger u, v, r, s;

            u = P.Copy();  // make copy to use inplace method
            v = X.Copy();

            int max = System.Math.Max(v._numberLength, u._numberLength);

            r            = new BigInteger(1, 1, new int[max + 1]);
            s            = new BigInteger(1, 1, new int[max + 1]);
            s._digits[0] = 1;

            int k    = 0;
            int lsbu = u.LowestSetBit;
            int lsbv = v.LowestSetBit;
            int toShift;

            if (lsbu > lsbv)
            {
                BitLevel.InplaceShiftRight(u, lsbu);
                BitLevel.InplaceShiftRight(v, lsbv);
                BitLevel.InplaceShiftLeft(r, lsbv);
                k += lsbu - lsbv;
            }
            else
            {
                BitLevel.InplaceShiftRight(u, lsbu);
                BitLevel.InplaceShiftRight(v, lsbv);
                BitLevel.InplaceShiftLeft(s, lsbu);
                k += lsbv - lsbu;
            }

            r._sign = 1;
            while (v.Signum() > 0)
            {
                // INV v >= 0, u >= 0, v odd, u odd (except last iteration when v is even (0))

                while (u.CompareTo(v) > BigInteger.EQUALS)
                {
                    Elementary.InplaceSubtract(u, v);
                    toShift = u.LowestSetBit;
                    BitLevel.InplaceShiftRight(u, toShift);
                    Elementary.InplaceAdd(r, s);
                    BitLevel.InplaceShiftLeft(s, toShift);
                    k += toShift;
                }

                while (u.CompareTo(v) <= BigInteger.EQUALS)
                {
                    Elementary.InplaceSubtract(v, u);

                    if (v.Signum() == 0)
                    {
                        break;
                    }

                    toShift = v.LowestSetBit;
                    BitLevel.InplaceShiftRight(v, toShift);
                    Elementary.InplaceAdd(s, r);
                    BitLevel.InplaceShiftLeft(r, toShift);
                    k += toShift;
                }
            }

            // in u is stored the gcd
            if (!u.IsOne())
            {
                throw new ArithmeticException("BigInteger not invertible.");
            }

            if (r.CompareTo(P) >= BigInteger.EQUALS)
            {
                Elementary.InplaceSubtract(r, P);
            }

            r = P.Subtract(r);

            // Have pair: ((BigInteger)r, (Integer)k) where r == a^(-1) * 2^k mod (module)
            int n1 = CalcN(P);

            if (k > m)
            {
                r = MonPro(r, BigInteger.One, P, n1);
                k = k - m;
            }

            r = MonPro(r, BigInteger.GetPowerOfTwo(m - k), P, n1);

            return(r);
        }
Ejemplo n.º 59
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));
        }
Ejemplo n.º 60
0
        public IAsymmetricCipherKeyPair GenerateKeyPair()
        {
            IBigInteger p, q, n, phi;

            //
            // p and q values should have a length of half the strength in bits
            //
            var strength    = _param.Strength;
            var pbitlength  = (strength + 1) / 2;
            var qbitlength  = (strength - pbitlength);
            var mindiffbits = strength / 3;

            var e = _param.PublicExponent;

            // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes)
            // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm")

            //
            // Generate p, prime and (p-1) relatively prime to e
            //
            for (; ;)
            {
                p = new BigInteger(pbitlength, 1, _param.Random);

                if (p.Mod(e).Equals(BigInteger.One))
                {
                    continue;
                }

                if (!p.IsProbablePrime(_param.Certainty))
                {
                    continue;
                }

                if (e.Gcd(p.Subtract(BigInteger.One)).Equals(BigInteger.One))
                {
                    break;
                }
            }

            //
            // Generate a modulus of the required length
            //
            for (; ;)
            {
                // Generate q, prime and (q-1) relatively prime to e,
                // and not equal to p
                //
                for (; ;)
                {
                    q = new BigInteger(qbitlength, 1, _param.Random);

                    if (q.Subtract(p).Abs().BitLength < mindiffbits)
                    {
                        continue;
                    }

                    if (q.Mod(e).Equals(BigInteger.One))
                    {
                        continue;
                    }

                    if (!q.IsProbablePrime(_param.Certainty))
                    {
                        continue;
                    }

                    if (e.Gcd(q.Subtract(BigInteger.One)).Equals(BigInteger.One))
                    {
                        break;
                    }
                }

                //
                // calculate the modulus
                //
                n = p.Multiply(q);

                if (n.BitLength == _param.Strength)
                {
                    break;
                }

                //
                // if we Get here our primes aren't big enough, make the largest
                // of the two p and try again
                //
                p = p.Max(q);
            }

            if (p.CompareTo(q) < 0)
            {
                phi = p;
                p   = q;
                q   = phi;
            }

            var pSub1 = p.Subtract(BigInteger.One);
            var qSub1 = q.Subtract(BigInteger.One);

            phi = pSub1.Multiply(qSub1);

            //
            // calculate the private exponent
            //
            var d = e.ModInverse(phi);

            //
            // calculate the CRT factors
            //

            var dP   = d.Remainder(pSub1);
            var dQ   = d.Remainder(qSub1);
            var qInv = q.ModInverse(p);

            return(new AsymmetricCipherKeyPair(
                       new RsaKeyParameters(false, n, e),
                       new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv)));
        }