예제 #1
0
        /**
         * Return a random IBigInteger 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 IBigInteger value in the range [min,max]
         */
        public static IBigInteger CreateRandomInRange(
            IBigInteger min,
            IBigInteger max,
            // TODO Should have been just Random class
            ISecureRandom 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)
            {
                IBigInteger 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));
        }
        /**
        * Return a random IBigInteger 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 IBigInteger value in the range [min,max]
        */
        public static IBigInteger CreateRandomInRange(
            IBigInteger min,
            IBigInteger max,
			// TODO Should have been just Random class
			ISecureRandom	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)
            {
                IBigInteger 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);
        }
        private static IBigInteger CalculateGenerator_FIPS186_2(IBigInteger p, IBigInteger q, SecureRandom r)
        {
            IBigInteger e = p.Subtract(BigInteger.One).Divide(q);
            IBigInteger pSub2 = p.Subtract(BigInteger.Two);

            for (;;)
            {
                IBigInteger h = BigIntegers.CreateRandomInRange(BigInteger.Two, pSub2, r);
                IBigInteger g = h.ModPow(e, p);

                if (g.BitLength > 1)
                    return g;
            }
        }
예제 #4
0
        /**
         * Partial modular reduction modulo
         * <code>(&#964;<sup>m</sup> - 1)/(&#964; - 1)</code>.
         * @param k The integer to be reduced.
         * @param m The bitlength of the underlying finite field.
         * @param a The parameter <code>a</code> of the elliptic curve.
         * @param s The auxiliary values <code>s<sub>0</sub></code> and
         * <code>s<sub>1</sub></code>.
         * @param mu The parameter &#956; of the elliptic curve.
         * @param c The precision (number of bits of accuracy) of the partial
         * modular reduction.
         * @return <code>&#961; := k partmod (&#964;<sup>m</sup> - 1)/(&#964; - 1)</code>
         */
        public static ZTauElement PartModReduction(IBigInteger k, int m, sbyte a,
                                                   IBigInteger[] s, sbyte mu, sbyte c)
        {
            // d0 = s[0] + mu*s[1]; mu is either 1 or -1
            IBigInteger d0;

            if (mu == 1)
            {
                d0 = s[0].Add(s[1]);
            }
            else
            {
                d0 = s[0].Subtract(s[1]);
            }

            IBigInteger[] v  = GetLucas(mu, m, true);
            IBigInteger   vm = v[1];

            SimpleBigDecimal lambda0 = ApproximateDivisionByN(
                k, s[0], vm, a, m, c);

            SimpleBigDecimal lambda1 = ApproximateDivisionByN(
                k, s[1], vm, a, m, c);

            ZTauElement q = Round(lambda0, lambda1, mu);

            // r0 = n - d0*q0 - 2*s1*q1
            IBigInteger r0 = k.Subtract(d0.Multiply(q.u)).Subtract(
                BigInteger.ValueOf(2).Multiply(s[1]).Multiply(q.v));

            // r1 = s1*q0 - s0*q1
            IBigInteger r1 = s[1].Multiply(q.u).Subtract(s[0].Multiply(q.v));

            return(new ZTauElement(r0, r1));
        }
        private static IBigInteger CalculateGenerator_FIPS186_3_Verifiable(IDigest d, IBigInteger p, IBigInteger q,
                                                                           byte[] seed, int index)
        {
            // A.2.3 Verifiable Canonical Generation of the Generator g
            IBigInteger e = p.Subtract(BigInteger.One).Divide(q);

            byte[] ggen = Hex.Decode("6767656E");

            // 7. U = domain_parameter_seed || "ggen" || index || count.
            byte[] U = new byte[seed.Length + ggen.Length + 1 + 2];
            Array.Copy(seed, 0, U, 0, seed.Length);
            Array.Copy(ggen, 0, U, seed.Length, ggen.Length);
            U[U.Length - 3] = (byte)index;

            byte[] w = new byte[d.GetDigestSize()];
            for (int count = 1; count < (1 << 16); ++count)
            {
                Inc(U);
                Hash(d, U, w);
                IBigInteger W = new BigInteger(1, w);
                IBigInteger g = W.ModPow(e, p);

                if (g.CompareTo(BigInteger.Two) >= 0)
                {
                    return(g);
                }
            }

            return(null);
        }
        private static IBigInteger CalculateGenerator_FIPS186_2(IBigInteger p, IBigInteger q, SecureRandom r)
        {
            IBigInteger e     = p.Subtract(BigInteger.One).Divide(q);
            IBigInteger pSub2 = p.Subtract(BigInteger.Two);

            for (;;)
            {
                IBigInteger h = BigIntegers.CreateRandomInRange(BigInteger.Two, pSub2, r);
                IBigInteger g = h.ModPow(e, p);

                if (g.BitLength > 1)
                {
                    return(g);
                }
            }
        }
예제 #7
0
        /**
         * Computes the norm of an element <code>&#955;</code> of
         * <code><b>Z</b>[&#964;]</code>.
         * @param mu The parameter <code>&#956;</code> of the elliptic curve.
         * @param lambda The element <code>&#955;</code> of
         * <code><b>Z</b>[&#964;]</code>.
         * @return The norm of <code>&#955;</code>.
         */
        public static IBigInteger Norm(sbyte mu, ZTauElement lambda)
        {
            IBigInteger norm;

            // s1 = u^2
            IBigInteger s1 = lambda.u.Multiply(lambda.u);

            // s2 = u * v
            IBigInteger s2 = lambda.u.Multiply(lambda.v);

            // s3 = 2 * v^2
            IBigInteger s3 = lambda.v.Multiply(lambda.v).ShiftLeft(1);

            if (mu == 1)
            {
                norm = s1.Add(s2).Add(s3);
            }
            else if (mu == -1)
            {
                norm = s1.Subtract(s2).Add(s3);
            }
            else
            {
                throw new ArgumentException("mu must be 1 or -1");
            }

            return(norm);
        }
        internal IBigInteger CalculatePrivate(
            DHParameters dhParams,
            ISecureRandom random)
        {
            int limit = dhParams.L;

            if (limit != 0)
            {
                return(new BigInteger(limit, random).SetBit(limit - 1));
            }

            IBigInteger min = BigInteger.Two;
            int         m   = dhParams.M;

            if (m != 0)
            {
                min = BigInteger.One.ShiftLeft(m - 1);
            }

            IBigInteger max = dhParams.P.Subtract(BigInteger.Two);
            IBigInteger q   = dhParams.Q;

            if (q != null)
            {
                max = q.Subtract(BigInteger.Two);
            }

            return(BigIntegers.CreateRandomInRange(min, max, random));
        }
예제 #9
0
        protected internal override ECPoint DecompressPoint(int yTilde, IBigInteger x1)
        {
            var x     = FromBigInteger(x1);
            var alpha = x.Multiply(x.Square().Add(this.A)).Add(this.B);
            var beta  = alpha.Sqrt();

            //
            // if we can't find a sqrt we haven't got a point on the
            // curve - run!
            //
            if (beta == null)
            {
                throw new ArithmeticException("Invalid point compression");
            }

            var betaValue = beta.ToBigInteger();
            var bit0      = betaValue.TestBit(0) ? 1 : 0;

            if (bit0 != yTilde)
            {
                // Use the other root
                beta = FromBigInteger(_q.Subtract(betaValue));
            }

            return(new FPPoint(this, x, beta, true));
        }
        /// <summary>
        /// Select a high order element of the multiplicative group Z
        ///
        /// p and q must be s.t. p = 2*q + 1, where p and q are prime (see generateSafePrimes)
        /// </summary>
        /// <param name="p">The p.</param>
        /// <param name="q">The q.</param>
        /// <param name="random">The random.</param>
        /// <returns></returns>
        internal static IBigInteger SelectGenerator(IBigInteger p, IBigInteger q, SecureRandom random)
        {
            var         pMinusTwo = p.Subtract(BigInteger.Two);
            IBigInteger g;

            /*
             * (see: Handbook of Applied Cryptography 4.80)
             */
            //			do
            //			{
            //				g = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusTwo, random);
            //			}
            //			while (g.ModPow(BigInteger.Two, p).Equals(BigInteger.One)
            //				|| g.ModPow(q, p).Equals(BigInteger.One));

            /*
             * RFC 2631 2.2.1.2 (and see: Handbook of Applied Cryptography 4.81)
             */
            do
            {
                var h = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusTwo, random);

                g = h.ModPow(BigInteger.Two, p);
            }while (g.Equals(BigInteger.One));

            return(g);
        }
예제 #11
0
        public DHParameters(
            IBigInteger p,
            IBigInteger g,
            IBigInteger q,
            int m,
            int l,
            IBigInteger 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;
        }
예제 #12
0
        public RsaSecretBcpgKey(IBigInteger d, IBigInteger p, IBigInteger q)
        {
            // PGP requires (p < q)
            var cmp = p.CompareTo(q);

            if (cmp >= 0)
            {
                if (cmp == 0)
                {
                    throw new ArgumentException("p and q cannot be equal");
                }

                var tmp = p;
                p = q;
                q = tmp;
            }

            _d = new MPInteger(d);
            _p = new MPInteger(p);
            _q = new MPInteger(q);
            _u = new MPInteger(p.ModInverse(q));

            _expP = d.Remainder(p.Subtract(BigInteger.One));
            _expQ = d.Remainder(q.Subtract(BigInteger.One));
            _crt  = q.ModInverse(p);
        }
예제 #13
0
        /**
         * Computes the Window NAF (non-adjacent Form) of an integer.
         * @param width The width <code>w</code> of the Window NAF. The width is
         * defined as the minimal number <code>w</code>, such that for any
         * <code>w</code> consecutive digits in the resulting representation, at
         * most one is non-zero.
         * @param k The integer of which the Window NAF is computed.
         * @return The Window NAF of the given width, such that the following holds:
         * <code>k = &#8722;<sub>i=0</sub><sup>l-1</sup> k<sub>i</sub>2<sup>i</sup>
         * </code>, where the <code>k<sub>i</sub></code> denote the elements of the
         * returned <code>sbyte[]</code>.
         */
        public sbyte[] WindowNaf(sbyte width, IBigInteger k)
        {
            // The window NAF is at most 1 element longer than the binary
            // representation of the integer k. sbyte can be used instead of short or
            // int unless the window width is larger than 8. For larger width use
            // short or int. However, a width of more than 8 is not efficient for
            // m = log2(q) smaller than 2305 Bits. Note: Values for m larger than
            // 1000 Bits are currently not used in practice.
            sbyte[] wnaf = new sbyte[k.BitLength + 1];

            // 2^width as short and BigInteger
            short       pow2wB  = (short)(1 << width);
            IBigInteger pow2wBI = BigInteger.ValueOf(pow2wB);

            int i = 0;

            // The actual length of the WNAF
            int length = 0;

            // while k >= 1
            while (k.SignValue > 0)
            {
                // if k is odd
                if (k.TestBit(0))
                {
                    // k Mod 2^width
                    IBigInteger remainder = k.Mod(pow2wBI);

                    // if remainder > 2^(width - 1) - 1
                    if (remainder.TestBit(width - 1))
                    {
                        wnaf[i] = (sbyte)(remainder.IntValue - pow2wB);
                    }
                    else
                    {
                        wnaf[i] = (sbyte)remainder.IntValue;
                    }
                    // wnaf[i] is now in [-2^(width-1), 2^(width-1)-1]

                    k      = k.Subtract(BigInteger.ValueOf(wnaf[i]));
                    length = i;
                }
                else
                {
                    wnaf[i] = 0;
                }

                // k = k/2
                k = k.ShiftRight(1);
                i++;
            }

            length++;

            // Reduce the WNAF array to its actual length
            sbyte[] wnafShort = new sbyte[length];
            Array.Copy(wnaf, 0, wnafShort, 0, length);
            return(wnafShort);
        }
예제 #14
0
        private IBigInteger CalculateS()
        {
            IBigInteger k   = Srp6Utilities.CalculateK(digest, N, g);
            IBigInteger exp = u.Multiply(x).Add(privA);
            IBigInteger tmp = g.ModPow(x, N).Multiply(k).Mod(N);

            return(B.Subtract(tmp).Mod(N).ModPow(exp, N));
        }
예제 #15
0
        public static IBigInteger GeneratePrivateValue(IDigest digest, IBigInteger N, IBigInteger g, SecureRandom random)
        {
            int         minBits = System.Math.Min(256, N.BitLength / 2);
            IBigInteger min     = BigInteger.One.ShiftLeft(minBits - 1);
            IBigInteger max     = N.Subtract(BigInteger.One);

            return(BigIntegers.CreateRandomInRange(min, max, random));
        }
        public static IBigInteger GeneratePrivateValue(IDigest digest, IBigInteger N, IBigInteger g, SecureRandom random)
        {
            int minBits = System.Math.Min(256, N.BitLength / 2);
            IBigInteger min = BigInteger.One.ShiftLeft(minBits - 1);
            IBigInteger max = N.Subtract(BigInteger.One);

            return BigIntegers.CreateRandomInRange(min, max, random);
        }
        private static IBigInteger GeneratePrivateKey(IBigInteger q, ISecureRandom random)
        {
            // TODO Prefer this method? (change test cases that used fixed random)
            // B.1.1 Key Pair Generation Using Extra Random Bits
//	        IBigInteger c = new BigInteger(q.BitLength + 64, random);
//	        return c.Mod(q.Subtract(BigInteger.One)).Add(BigInteger.One);

            // B.1.2 Key Pair Generation by Testing Candidates
            return(BigIntegers.CreateRandomInRange(BigInteger.One, q.Subtract(BigInteger.One), random));
        }
        private static IBigInteger GeneratePrivateKey(IBigInteger q, ISecureRandom random)
        {
            // TODO Prefer this method? (change test cases that used fixed random)
            // B.1.1 Key Pair Generation Using Extra Random Bits
            //	        IBigInteger c = new BigInteger(q.BitLength + 64, random);
            //	        return c.Mod(q.Subtract(BigInteger.One)).Add(BigInteger.One);

            // B.1.2 Key Pair Generation by Testing Candidates
            return BigIntegers.CreateRandomInRange(BigInteger.One, q.Subtract(BigInteger.One), random);
        }
예제 #19
0
        // Section 7.2.5 ECSP-NR, pg 34

        /**
         * generate a signature for the given message using the key we were
         * initialised with.  Generally, the order of the curve should be at
         * least as long as the hash of the message of interest, and with
         * ECNR it *must* be at least as long.
         *
         * @param digest  the digest to be signed.
         * @exception DataLengthException if the digest is longer than the key allows
         */
        public IBigInteger[] GenerateSignature(
            byte[] message)
        {
            if (!this._forSigning)
            {
                // not properly initilaized... deal with it
                throw new InvalidOperationException("not initialised for signing");
            }

            IBigInteger n          = ((ECPrivateKeyParameters)this._key).Parameters.N;
            int         nBitLength = n.BitLength;

            IBigInteger e          = new BigInteger(1, message);
            int         eBitLength = e.BitLength;

            ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)_key;

            if (eBitLength > nBitLength)
            {
                throw new DataLengthException("input too large for ECNR key.");
            }

            IBigInteger r = null;
            IBigInteger s = null;

            IAsymmetricCipherKeyPair tempPair;

            do             // generate r
            {
                // generate another, but very temporary, key pair using
                // the same EC parameters
                ECKeyPairGenerator keyGen = new ECKeyPairGenerator();

                keyGen.Init(new ECKeyGenerationParameters(privKey.Parameters, _random));

                tempPair = keyGen.GenerateKeyPair();

                //    IBigInteger Vx = tempPair.getPublic().getW().getAffineX();
                ECPublicKeyParameters V  = (ECPublicKeyParameters)tempPair.Public; // get temp's public key
                IBigInteger           Vx = V.Q.X.ToBigInteger();                   // get the point's x coordinate

                r = Vx.Add(e).Mod(n);
            }while (r.SignValue == 0);

            // generate s
            IBigInteger x = privKey.D;                                    // private key value
            IBigInteger u = ((ECPrivateKeyParameters)tempPair.Private).D; // temp's private key value

            s = u.Subtract(r.Multiply(x)).Mod(n);

            return(new IBigInteger[] { r, s });
        }
예제 #20
0
        public void TestDivideAndRemainder()
        {
            // TODO More basic tests

            IBigInteger n = new BigInteger(48, _random);

            IBigInteger[] qr = n.DivideAndRemainder(one);
            Assert.AreEqual(n, qr[0]);
            Assert.AreEqual(zero, qr[1]);

            for (int rep = 0; rep < 10; ++rep)
            {
                IBigInteger   a  = new BigInteger(100 - rep, 0, _random);
                IBigInteger   b  = new BigInteger(100 + rep, 0, _random);
                IBigInteger   c  = new BigInteger(10 + rep, 0, _random);
                IBigInteger   d  = a.Multiply(b).Add(c);
                IBigInteger[] es = d.DivideAndRemainder(a);

                Assert.AreEqual(b, es[0]);
                Assert.AreEqual(c, es[1]);
            }

            // Special tests for power of two since uses different code path internally
            for (int i = 0; i < 100; ++i)
            {
                int         shift  = _random.Next(64);
                IBigInteger a      = one.ShiftLeft(shift);
                IBigInteger b      = new BigInteger(64 + _random.Next(64), _random);
                IBigInteger bShift = b.ShiftRight(shift);
                IBigInteger bMod   = b.And(a.Subtract(one));

                string data = "shift=" + shift + ", b=" + b.ToString(16);

                qr = b.DivideAndRemainder(a);
                Assert.AreEqual(bShift, qr[0], data);
                Assert.AreEqual(bMod, qr[1], data);

                qr = b.DivideAndRemainder(a.Negate());
                Assert.AreEqual(bShift.Negate(), qr[0], data);
                Assert.AreEqual(bMod, qr[1], data);

                qr = b.Negate().DivideAndRemainder(a);
                Assert.AreEqual(bShift.Negate(), qr[0], data);
                Assert.AreEqual(bMod.Negate(), qr[1], data);

                qr = b.Negate().DivideAndRemainder(a.Negate());
                Assert.AreEqual(bShift, qr[0], data);
                Assert.AreEqual(bMod.Negate(), qr[1], data);
            }
        }
예제 #21
0
        protected virtual DHPublicKeyParameters ValidateDHPublicKey(DHPublicKeyParameters key)
        {
            IBigInteger  Y          = key.Y;
            DHParameters parameters = key.Parameters;
            IBigInteger  p          = parameters.P;
            IBigInteger  g          = parameters.G;

            if (!p.IsProbablePrime(2))
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }
            if (g.CompareTo(BigInteger.Two) < 0 || g.CompareTo(p.Subtract(BigInteger.Two)) > 0)
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }
            if (Y.CompareTo(BigInteger.Two) < 0 || Y.CompareTo(p.Subtract(BigInteger.One)) > 0)
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }

            // TODO See RFC 2631 for more discussion of Diffie-Hellman validation

            return(key);
        }
예제 #22
0
        // Section 7.2.6 ECVP-NR, pg 35

        /**
         * return true if the value r and s represent a signature for the
         * message passed in. Generally, the order of the curve should be at
         * least as long as the hash of the message of interest, and with
         * ECNR, it *must* be at least as long.  But just in case the signer
         * applied mod(n) to the longer digest, this implementation will
         * apply mod(n) during verification.
         *
         * @param digest  the digest to be verified.
         * @param r       the r value of the signature.
         * @param s       the s value of the signature.
         * @exception DataLengthException if the digest is longer than the key allows
         */
        public bool VerifySignature(
            byte[]          message,
            IBigInteger r,
            IBigInteger s)
        {
            if (this._forSigning)
            {
                // not properly initilaized... deal with it
                throw new InvalidOperationException("not initialised for verifying");
            }

            ECPublicKeyParameters pubKey = (ECPublicKeyParameters)_key;
            IBigInteger           n      = pubKey.Parameters.N;
            int nBitLength = n.BitLength;

            IBigInteger e          = new BigInteger(1, message);
            int         eBitLength = e.BitLength;

            if (eBitLength > nBitLength)
            {
                throw new DataLengthException("input too large for ECNR key.");
            }

            // r in the range [1,n-1]
            if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
            {
                return(false);
            }

            // TODO So why is this different from the spec?
            // s in the range [0,n-1]           NB: ECNR spec says 0
            if (s.CompareTo(BigInteger.Zero) < 0 || s.CompareTo(n) >= 0)
            {
                return(false);
            }

            // compute P = sG + rW

            ECPoint G = pubKey.Parameters.G;
            ECPoint W = pubKey.Q;
            // calculate P using Bouncy math
            ECPoint P = ECAlgorithms.SumOfTwoMultiplies(G, s, W, r);

            IBigInteger x = P.X.ToBigInteger();
            IBigInteger t = r.Subtract(x).Mod(n);

            return(t.Equals(e));
        }
예제 #23
0
        /**
         * Calculates the Lucas Sequence elements <code>U<sub>k-1</sub></code> and
         * <code>U<sub>k</sub></code> or <code>V<sub>k-1</sub></code> and
         * <code>V<sub>k</sub></code>.
         * @param mu The parameter <code>&#956;</code> of the elliptic curve.
         * @param k The index of the second element of the Lucas Sequence to be
         * returned.
         * @param doV If set to true, computes <code>V<sub>k-1</sub></code> and
         * <code>V<sub>k</sub></code>, otherwise <code>U<sub>k-1</sub></code> and
         * <code>U<sub>k</sub></code>.
         * @return An array with 2 elements, containing <code>U<sub>k-1</sub></code>
         * and <code>U<sub>k</sub></code> or <code>V<sub>k-1</sub></code>
         * and <code>V<sub>k</sub></code>.
         */
        public static IBigInteger[] GetLucas(sbyte mu, int k, bool doV)
        {
            if (!(mu == 1 || mu == -1))
            {
                throw new ArgumentException("mu must be 1 or -1");
            }

            IBigInteger u0;
            IBigInteger u1;
            IBigInteger u2;

            if (doV)
            {
                u0 = BigInteger.Two;
                u1 = BigInteger.ValueOf(mu);
            }
            else
            {
                u0 = BigInteger.Zero;
                u1 = BigInteger.One;
            }

            for (int i = 1; i < k; i++)
            {
                // u2 = mu*u1 - 2*u0;
                IBigInteger s = null;
                if (mu == 1)
                {
                    s = u1;
                }
                else
                {
                    // mu == -1
                    s = u1.Negate();
                }

                u2 = s.Subtract(u0.ShiftLeft(1));
                u0 = u1;
                u1 = u2;
                //            System.out.println(i + ": " + u2);
                //            System.out.println();
            }

            IBigInteger[] retVal = { u0, u1 };
            return(retVal);
        }
예제 #24
0
        public void TestMod()
        {
            // TODO Basic tests

            for (int rep = 0; rep < 100; ++rep)
            {
                int         diff = _random.Next(25);
                IBigInteger a    = new BigInteger(100 - diff, 0, _random);
                IBigInteger b    = new BigInteger(100 + diff, 0, _random);
                IBigInteger c    = new BigInteger(10 + diff, 0, _random);

                IBigInteger d = a.Multiply(b).Add(c);
                IBigInteger e = d.Mod(a);
                Assert.AreEqual(c, e);

                IBigInteger pow2 = one.ShiftLeft(_random.Next(128));
                Assert.AreEqual(b.And(pow2.Subtract(one)), b.Mod(pow2));
            }
        }
예제 #25
0
        public void TestModPow()
        {
            try
            {
                two.ModPow(one, zero);
                Assert.Fail("expected ArithmeticException");
            }
            catch (ArithmeticException) {}

            Assert.AreEqual(zero, zero.ModPow(zero, one));
            Assert.AreEqual(one, zero.ModPow(zero, two));
            Assert.AreEqual(zero, two.ModPow(one, one));
            Assert.AreEqual(one, two.ModPow(zero, two));

            for (int i = 0; i < 10; ++i)
            {
                IBigInteger m = BigInteger.ProbablePrime(10 + i * 3, _random);
                IBigInteger x = new BigInteger(m.BitLength - 1, _random);

                Assert.AreEqual(x, x.ModPow(m, m));
                if (x.SignValue != 0)
                {
                    Assert.AreEqual(zero, zero.ModPow(x, m));
                    Assert.AreEqual(one, x.ModPow(m.Subtract(one), m));
                }

                IBigInteger y  = new BigInteger(m.BitLength - 1, _random);
                IBigInteger n  = new BigInteger(m.BitLength - 1, _random);
                IBigInteger n3 = n.ModPow(three, m);

                IBigInteger resX = n.ModPow(x, m);
                IBigInteger resY = n.ModPow(y, m);
                IBigInteger res  = resX.Multiply(resY).Mod(m);
                IBigInteger res3 = res.ModPow(three, m);

                Assert.AreEqual(res3, n3.ModPow(x.Add(y), m));

                IBigInteger a = x.Add(one);                 // Make sure it's not zero
                IBigInteger b = y.Add(one);                 // Make sure it's not zero

                Assert.AreEqual(a.ModPow(b, m).ModInverse(m), a.ModPow(b.Negate(), m));
            }
        }
        public DHParameters(
            IBigInteger p,
            IBigInteger g,
            IBigInteger q,
			int						m,
			int						l,
            IBigInteger 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;
        }
예제 #27
0
        /**
         * Process a single block using the basic RSA algorithm.
         *
         * @param inBuf the input array.
         * @param inOff the offset into the input buffer where the data starts.
         * @param inLen the length of the data to be processed.
         * @return the result of the RSA process.
         * @exception DataLengthException the input block is too large.
         */
        public byte[] ProcessBlock(
            byte[]  inBuf,
            int inOff,
            int inLen)
        {
            if (key == null)
            {
                throw new InvalidOperationException("RSA engine not initialised");
            }

            IBigInteger input = core.ConvertInput(inBuf, inOff, inLen);

            IBigInteger result;

            if (key is RsaPrivateCrtKeyParameters)
            {
                RsaPrivateCrtKeyParameters k = (RsaPrivateCrtKeyParameters)key;
                IBigInteger e = k.PublicExponent;
                if (e != null)                   // can't do blinding without a public exponent
                {
                    IBigInteger m = k.Modulus;
                    IBigInteger r = BigIntegers.CreateRandomInRange(
                        BigInteger.One, m.Subtract(BigInteger.One), random);

                    IBigInteger blindedInput  = r.ModPow(e, m).Multiply(input).Mod(m);
                    IBigInteger blindedResult = core.ProcessBlock(blindedInput);

                    IBigInteger rInv = r.ModInverse(m);
                    result = blindedResult.Multiply(rInv).Mod(m);
                }
                else
                {
                    result = core.ProcessBlock(input);
                }
            }
            else
            {
                result = core.ProcessBlock(input);
            }

            return(core.ConvertOutput(result));
        }
예제 #28
0
        public void TestMultiply()
        {
            IBigInteger one = BigInteger.One;

            Assert.AreEqual(one, one.Negate().Multiply(one.Negate()));

            for (int i = 0; i < 100; ++i)
            {
                int aLen = 64 + _random.Next(64);
                int bLen = 64 + _random.Next(64);

                IBigInteger a = new BigInteger(aLen, _random).SetBit(aLen);
                IBigInteger b = new BigInteger(bLen, _random).SetBit(bLen);
                IBigInteger c = new BigInteger(32, _random);

                IBigInteger ab = a.Multiply(b);
                IBigInteger bc = b.Multiply(c);

                Assert.AreEqual(ab.Add(bc), a.Add(c).Multiply(b));
                Assert.AreEqual(ab.Subtract(bc), a.Subtract(c).Multiply(b));
            }

            // Special tests for power of two since uses different code path internally
            for (int i = 0; i < 100; ++i)
            {
                int         shift  = _random.Next(64);
                IBigInteger a      = one.ShiftLeft(shift);
                IBigInteger b      = new BigInteger(64 + _random.Next(64), _random);
                IBigInteger bShift = b.ShiftLeft(shift);

                Assert.AreEqual(bShift, a.Multiply(b));
                Assert.AreEqual(bShift.Negate(), a.Multiply(b.Negate()));
                Assert.AreEqual(bShift.Negate(), a.Negate().Multiply(b));
                Assert.AreEqual(bShift, a.Negate().Multiply(b.Negate()));

                Assert.AreEqual(bShift, b.Multiply(a));
                Assert.AreEqual(bShift.Negate(), b.Multiply(a.Negate()));
                Assert.AreEqual(bShift.Negate(), b.Negate().Multiply(a));
                Assert.AreEqual(bShift, b.Negate().Multiply(a.Negate()));
            }
        }
        /**
         * Procedure C
         * procedure generates the a value from the given p,q,
         * returning the a value.
         */
        private IBigInteger procedure_C(IBigInteger p, IBigInteger q)
        {
            IBigInteger pSub1     = p.Subtract(BigInteger.One);
            IBigInteger pSub1Divq = pSub1.Divide(q);

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

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

                    if (a.CompareTo(BigInteger.One) != 0)
                    {
                        return(a);
                    }
                }
            }
        }
예제 #30
0
        /**
         * return true if the value r and s represent a GOST3410 signature for
         * the passed in message (for standard GOST3410 the message should be
         * a GOST3411 hash of the real message to be verified).
         */
        public bool VerifySignature(
            byte[]          message,
            IBigInteger r,
            IBigInteger s)
        {
            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];
            }

            IBigInteger e = new BigInteger(1, mRev);
            IBigInteger n = key.Parameters.N;

            // r in the range [1,n-1]
            if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
            {
                return(false);
            }

            // s in the range [1,n-1]
            if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0)
            {
                return(false);
            }

            IBigInteger v = e.ModInverse(n);

            IBigInteger z1 = s.Multiply(v).Mod(n);
            IBigInteger z2 = (n.Subtract(r)).Multiply(v).Mod(n);

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

            ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2);

            IBigInteger R = point.X.ToBigInteger().Mod(n);

            return(R.Equals(r));
        }
        public RsaSecretBcpgKey(IBigInteger d, IBigInteger p, IBigInteger q)
        {
            // PGP requires (p < q)
            var cmp = p.CompareTo(q);
            if (cmp >= 0)
            {
                if (cmp == 0)
                    throw new ArgumentException("p and q cannot be equal");

                var tmp = p;
                p = q;
                q = tmp;
            }

            _d = new MPInteger(d);
            _p = new MPInteger(p);
            _q = new MPInteger(q);
            _u = new MPInteger(p.ModInverse(q));

            _expP = d.Remainder(p.Subtract(BigInteger.One));
            _expQ = d.Remainder(q.Subtract(BigInteger.One));
            _crt = q.ModInverse(p);
        }
 public SimpleBigDecimal Subtract(IBigInteger b)
 {
     return(new SimpleBigDecimal(bigInt.Subtract(b.ShiftLeft(scale)), scale));
 }
예제 #33
0
        /**
         * Computes the <code>&#964;</code>-adic NAF (non-adjacent form) of an
         * element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>.
         * @param mu The parameter <code>&#956;</code> of the elliptic curve.
         * @param lambda The element <code>&#955;</code> of
         * <code><b>Z</b>[&#964;]</code>.
         * @return The <code>&#964;</code>-adic NAF of <code>&#955;</code>.
         */
        public static sbyte[] TauAdicNaf(sbyte mu, ZTauElement lambda)
        {
            if (!((mu == 1) || (mu == -1)))
            {
                throw new ArgumentException("mu must be 1 or -1");
            }

            IBigInteger 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 : 34;

            // The array holding the TNAF
            sbyte[] u = new sbyte[maxLength];
            int     i = 0;

            // The actual length of the TNAF
            int length = 0;

            IBigInteger r0 = lambda.u;
            IBigInteger r1 = lambda.v;

            while (!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero))))
            {
                // If r0 is odd
                if (r0.TestBit(0))
                {
                    u[i] = (sbyte)BigInteger.Two.Subtract((r0.Subtract(r1.ShiftLeft(1))).Mod(Four)).IntValue;

                    // r0 = r0 - u[i]
                    if (u[i] == 1)
                    {
                        r0 = r0.ClearBit(0);
                    }
                    else
                    {
                        // u[i] == -1
                        r0 = r0.Add(BigInteger.One);
                    }
                    length = i;
                }
                else
                {
                    u[i] = 0;
                }

                IBigInteger t = r0;
                IBigInteger s = r0.ShiftRight(1);
                if (mu == 1)
                {
                    r0 = r1.Add(s);
                }
                else
                {
                    // mu == -1
                    r0 = r1.Subtract(s);
                }

                r1 = t.ShiftRight(1).Negate();
                i++;
            }

            length++;

            // Reduce the TNAF array to its actual length
            sbyte[] tnaf = new sbyte[length];
            Array.Copy(u, 0, tnaf, 0, length);
            return(tnaf);
        }
        /// <summary>
        /// Select a high order element of the multiplicative group Z
        ///
        /// p and q must be s.t. p = 2*q + 1, where p and q are prime (see generateSafePrimes)
        /// </summary>
        /// <param name="p">The p.</param>
        /// <param name="q">The q.</param>
        /// <param name="random">The random.</param>
        /// <returns></returns>
        internal static IBigInteger SelectGenerator(IBigInteger p, IBigInteger q, SecureRandom random)
        {
            var pMinusTwo = p.Subtract(BigInteger.Two);
            IBigInteger g;

            /*
             * (see: Handbook of Applied Cryptography 4.80)
             */
            //			do
            //			{
            //				g = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusTwo, random);
            //			}
            //			while (g.ModPow(BigInteger.Two, p).Equals(BigInteger.One)
            //				|| g.ModPow(q, p).Equals(BigInteger.One));

            /*
             * RFC 2631 2.2.1.2 (and see: Handbook of Applied Cryptography 4.81)
             */
            do
            {
                var h = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusTwo, random);

                g = h.ModPow(BigInteger.Two, p);
            }
            while (g.Equals(BigInteger.One));

            return g;
        }
        /**
         * @exception InvalidCipherTextException if the decrypted block is not a valid ISO 9796 bit string
         */
        private byte[] DecodeBlock(
            byte[]  input,
            int inOff,
            int inLen)
        {
            byte[] block = engine.ProcessBlock(input, inOff, inLen);
            int    r     = 1;
            int    t     = (bitSize + 13) / 16;

            IBigInteger iS = new BigInteger(1, block);
            IBigInteger iR;

            if (iS.Mod(Sixteen).Equals(Six))
            {
                iR = iS;
            }
            else
            {
                iR = modulus.Subtract(iS);

                if (!iR.Mod(Sixteen).Equals(Six))
                {
                    throw new InvalidCipherTextException("resulting integer iS or (modulus - iS) is not congruent to 6 mod 16");
                }
            }

            block = iR.ToByteArrayUnsigned();

            if ((block[block.Length - 1] & 0x0f) != 0x6)
            {
                throw new InvalidCipherTextException("invalid forcing byte in block");
            }

            block[block.Length - 1] =
                (byte)(((ushort)(block[block.Length - 1] & 0xff) >> 4)
                       | ((inverse[(block[block.Length - 2] & 0xff) >> 4]) << 4));

            block[0] = (byte)((shadows[(uint)(block[1] & 0xff) >> 4] << 4)
                              | shadows[block[1] & 0x0f]);

            bool boundaryFound = false;
            int  boundary      = 0;

            for (int i = block.Length - 1; i >= block.Length - 2 * t; i -= 2)
            {
                int val = ((shadows[(uint)(block[i] & 0xff) >> 4] << 4)
                           | shadows[block[i] & 0x0f]);

                if (((block[i - 1] ^ val) & 0xff) != 0)
                {
                    if (!boundaryFound)
                    {
                        boundaryFound = true;
                        r             = (block[i - 1] ^ val) & 0xff;
                        boundary      = i - 1;
                    }
                    else
                    {
                        throw new InvalidCipherTextException("invalid tsums in block");
                    }
                }
            }

            block[boundary] = 0;

            byte[] nblock = new byte[(block.Length - boundary) / 2];

            for (int i = 0; i < nblock.Length; i++)
            {
                nblock[i] = block[2 * i + boundary + 1];
            }

            padBits = r - 1;

            return(nblock);
        }
예제 #36
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, IBigInteger pow2w, IBigInteger tw, ZTauElement[] alpha)
        {
            if (!((mu == 1) || (mu == -1)))
            {
                throw new ArgumentException("mu must be 1 or -1");
            }

            IBigInteger 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
            sbyte[] u = new sbyte[maxLength];

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

            // Split lambda into two BigIntegers to simplify calculations
            IBigInteger r0 = lambda.u;
            IBigInteger 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
                    IBigInteger 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;
                }

                IBigInteger 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);
        }
        private static IBigInteger CalculateGenerator_FIPS186_3_Verifiable(IDigest d, IBigInteger p, IBigInteger q,
			byte[] seed, int index)
        {
            // A.2.3 Verifiable Canonical Generation of the Generator g
            IBigInteger e = p.Subtract(BigInteger.One).Divide(q);
            byte[] ggen = Hex.Decode("6767656E");

            // 7. U = domain_parameter_seed || "ggen" || index || count.
            byte[] U = new byte[seed.Length + ggen.Length + 1 + 2];
            Array.Copy(seed, 0, U, 0, seed.Length);
            Array.Copy(ggen, 0, U, seed.Length, ggen.Length);
            U[U.Length - 3] = (byte)index;

            byte[] w = new byte[d.GetDigestSize()];
            for (int count = 1; count < (1 << 16); ++count)
            {
                Inc(U);
                Hash(d, U, w);
                IBigInteger W = new BigInteger(1, w);
                IBigInteger g = W.ModPow(e, p);

                if (g.CompareTo(BigInteger.Two) >= 0)
                    return g;
            }

            return null;
        }
        // Section 7.2.6 ECVP-NR, pg 35
        /**
         * return true if the value r and s represent a signature for the
         * message passed in. Generally, the order of the curve should be at
         * least as long as the hash of the message of interest, and with
         * ECNR, it *must* be at least as long.  But just in case the signer
         * applied mod(n) to the longer digest, this implementation will
         * apply mod(n) during verification.
         *
         * @param digest  the digest to be verified.
         * @param r       the r value of the signature.
         * @param s       the s value of the signature.
         * @exception DataLengthException if the digest is longer than the key allows
         */
        public bool VerifySignature(
			byte[]		message,
            IBigInteger r,
            IBigInteger s)
        {
            if (this._forSigning)
            {
                // not properly initilaized... deal with it
                throw new InvalidOperationException("not initialised for verifying");
            }

            ECPublicKeyParameters pubKey = (ECPublicKeyParameters)_key;
            IBigInteger n = pubKey.Parameters.N;
            int nBitLength = n.BitLength;

            IBigInteger e = new BigInteger(1, message);
            int eBitLength = e.BitLength;

            if (eBitLength > nBitLength)
            {
                throw new DataLengthException("input too large for ECNR key.");
            }

            // r in the range [1,n-1]
            if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
            {
                return false;
            }

            // TODO So why is this different from the spec?
            // s in the range [0,n-1]           NB: ECNR spec says 0
            if (s.CompareTo(BigInteger.Zero) < 0 || s.CompareTo(n) >= 0)
            {
                return false;
            }

            // compute P = sG + rW

            ECPoint G = pubKey.Parameters.G;
            ECPoint W = pubKey.Q;
            // calculate P using Bouncy math
            ECPoint P = ECAlgorithms.SumOfTwoMultiplies(G, s, W, r);

            IBigInteger x = P.X.ToBigInteger();
            IBigInteger t = r.Subtract(x).Mod(n);

            return t.Equals(e);
        }
예제 #39
0
        /**
        * Partial modular reduction modulo
        * <code>(&#964;<sup>m</sup> - 1)/(&#964; - 1)</code>.
        * @param k The integer to be reduced.
        * @param m The bitlength of the underlying finite field.
        * @param a The parameter <code>a</code> of the elliptic curve.
        * @param s The auxiliary values <code>s<sub>0</sub></code> and
        * <code>s<sub>1</sub></code>.
        * @param mu The parameter &#956; of the elliptic curve.
        * @param c The precision (number of bits of accuracy) of the partial
        * modular reduction.
        * @return <code>&#961; := k partmod (&#964;<sup>m</sup> - 1)/(&#964; - 1)</code>
        */
        public static ZTauElement PartModReduction(IBigInteger k, int m, sbyte a,
            IBigInteger[] s, sbyte mu, sbyte c)
        {
            // d0 = s[0] + mu*s[1]; mu is either 1 or -1
            IBigInteger d0;
            if (mu == 1)
            {
                d0 = s[0].Add(s[1]);
            }
            else
            {
                d0 = s[0].Subtract(s[1]);
            }

            IBigInteger[] v = GetLucas(mu, m, true);
            IBigInteger vm = v[1];

            SimpleBigDecimal lambda0 = ApproximateDivisionByN(
                k, s[0], vm, a, m, c);

            SimpleBigDecimal lambda1 = ApproximateDivisionByN(
                k, s[1], vm, a, m, c);

            ZTauElement q = Round(lambda0, lambda1, mu);

            // r0 = n - d0*q0 - 2*s1*q1
            IBigInteger r0 = k.Subtract(d0.Multiply(q.u)).Subtract(
                BigInteger.ValueOf(2).Multiply(s[1]).Multiply(q.v));

            // r1 = s1*q0 - s0*q1
            IBigInteger r1 = s[1].Multiply(q.u).Subtract(s[0].Multiply(q.v));

            return new ZTauElement(r0, r1);
        }
        /**
        * Computes the Window NAF (non-adjacent Form) of an integer.
        * @param width The width <code>w</code> of the Window NAF. The width is
        * defined as the minimal number <code>w</code>, such that for any
        * <code>w</code> consecutive digits in the resulting representation, at
        * most one is non-zero.
        * @param k The integer of which the Window NAF is computed.
        * @return The Window NAF of the given width, such that the following holds:
        * <code>k = &#8722;<sub>i=0</sub><sup>l-1</sup> k<sub>i</sub>2<sup>i</sup>
        * </code>, where the <code>k<sub>i</sub></code> denote the elements of the
        * returned <code>sbyte[]</code>.
        */
        public sbyte[] WindowNaf(sbyte width, IBigInteger k)
        {
            // The window NAF is at most 1 element longer than the binary
            // representation of the integer k. sbyte can be used instead of short or
            // int unless the window width is larger than 8. For larger width use
            // short or int. However, a width of more than 8 is not efficient for
            // m = log2(q) smaller than 2305 Bits. Note: Values for m larger than
            // 1000 Bits are currently not used in practice.
            sbyte[] wnaf = new sbyte[k.BitLength + 1];

            // 2^width as short and BigInteger
            short pow2wB = (short)(1 << width);
            IBigInteger pow2wBI = BigInteger.ValueOf(pow2wB);

            int i = 0;

            // The actual length of the WNAF
            int length = 0;

            // while k >= 1
            while (k.SignValue > 0)
            {
                // if k is odd
                if (k.TestBit(0))
                {
                    // k Mod 2^width
                    IBigInteger remainder = k.Mod(pow2wBI);

                    // if remainder > 2^(width - 1) - 1
                    if (remainder.TestBit(width - 1))
                    {
                        wnaf[i] = (sbyte)(remainder.IntValue - pow2wB);
                    }
                    else
                    {
                        wnaf[i] = (sbyte)remainder.IntValue;
                    }
                    // wnaf[i] is now in [-2^(width-1), 2^(width-1)-1]

                    k = k.Subtract(BigInteger.ValueOf(wnaf[i]));
                    length = i;
                }
                else
                {
                    wnaf[i] = 0;
                }

                // k = k/2
                k = k.ShiftRight(1);
                i++;
            }

            length++;

            // Reduce the WNAF array to its actual length
            sbyte[] wnafShort = new sbyte[length];
            Array.Copy(wnaf, 0, wnafShort, 0, length);
            return wnafShort;
        }
        public IBigInteger Add(
            IBigInteger value)
        {
            if (this.SignValue == 0)
                return value;

            if (this.SignValue != value.SignValue)
            {
                if (value.SignValue == 0)
                    return this;

                if (value.SignValue < 0)
                    return Subtract(value.Negate());

                return value.Subtract(Negate());
            }

            return AddToMagnitude(value.Magnitude);
        }
예제 #42
0
        /// <summary>
        /// D.1.4 91
        /// return a sqrt root - the routine verifies that the calculation
        /// returns the right value - if none exists it returns null.
        /// </summary>
        /// <returns></returns>
        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
                var z = new FPFieldElement(_q, _x.ModPow(_q.ShiftRight(2).Add(BigInteger.One), _q));

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

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

            var legendreExponent = qMinusOne.ShiftRight(1);

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

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

            var Q     = _x;
            var fourQ = Q.ShiftLeft(2).Mod(_q);

            IBigInteger U;
            IBigInteger V;

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

                var result = FastLucasSequence(_q, P, Q, k);
                U = result[0];
                V = result[1];

                if (!V.Multiply(V).Mod(_q).Equals(fourQ))
                {
                    continue;
                }

                // 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);
        }
        /**
         * Procedure C
         * procedure generates the a value from the given p,q,
         * returning the a value.
         */
        private IBigInteger procedure_C(IBigInteger p, IBigInteger q)
        {
            IBigInteger pSub1 = p.Subtract(BigInteger.One);
            IBigInteger pSub1Divq = pSub1.Divide(q);

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

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

                    if (a.CompareTo(BigInteger.One) != 0)
                    {
                        return a;
                    }
                }
            }
        }