Exemplo n.º 1
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);
        }
Exemplo n.º 2
0
        private static IBigInteger allocateSerialNumber()
        {
            IBigInteger _tmp = serialNumber;

            serialNumber = serialNumber.Add(BigInteger.One);
            return(_tmp);
        }
Exemplo n.º 3
0
        /**
         * Initializes this algorithm. Must be called before all other Functions.
         *
         * @see org.bouncycastle.crypto.AsymmetricBlockCipher#init(bool,
         *      org.bouncycastle.crypto.CipherParameters)
         */
        public void Init(
            bool forEncryption,
            ICipherParameters parameters)
        {
            this.forEncryption = forEncryption;

            if (parameters is ParametersWithRandom)
            {
                parameters = ((ParametersWithRandom)parameters).Parameters;
            }

            key = (NaccacheSternKeyParameters)parameters;

            // construct lookup table for faster decryption if necessary
            if (!this.forEncryption)
            {
#if !NETFX_CORE
                if (debug)
                {
                    Console.WriteLine("Constructing lookup Array");
                }
#endif
                NaccacheSternPrivateKeyParameters priv = (NaccacheSternPrivateKeyParameters)key;
                IList primes = priv.SmallPrimesList;
                lookup = new IList[primes.Count];
                for (int i = 0; i < primes.Count; i++)
                {
                    IBigInteger actualPrime      = (BigInteger)primes[i];
                    int         actualPrimeValue = actualPrime.IntValue;

                    lookup[i] = Platform.CreateArrayList(actualPrimeValue);
                    lookup[i].Add(BigInteger.One);

#if !NETFX_CORE
                    if (debug)
                    {
                        Console.WriteLine("Constructing lookup ArrayList for " + actualPrimeValue);
                    }
#endif

                    IBigInteger accJ = BigInteger.Zero;

                    for (int j = 1; j < actualPrimeValue; j++)
                    {
                        //						IBigInteger bigJ = BigInteger.ValueOf(j);
                        //						accJ = priv.PhiN.Multiply(bigJ);
                        accJ = accJ.Add(priv.PhiN);
                        IBigInteger comp = accJ.Divide(actualPrime);
                        lookup[i].Add(priv.G.ModPow(comp, priv.Modulus));
                    }
                }
            }
        }
Exemplo n.º 4
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 });
        }
        public void TestNextProbablePrime()
        {
            IBigInteger firstPrime = BigInteger.ProbablePrime(32, _random);
            IBigInteger nextPrime  = firstPrime.NextProbablePrime();

            Assert.IsTrue(firstPrime.IsProbablePrime(10));
            Assert.IsTrue(nextPrime.IsProbablePrime(10));

            IBigInteger check = firstPrime.Add(one);

            while (check.CompareTo(nextPrime) < 0)
            {
                Assert.IsFalse(check.IsProbablePrime(10));
                check = check.Add(one);
            }
        }
        public override string ToString()
        {
            if (scale == 0)
            {
                return(bigInt.ToString());
            }

            IBigInteger floorBigInt = Floor();

            IBigInteger fract = bigInt.Subtract(floorBigInt.ShiftLeft(scale));

            if (bigInt.SignValue < 0)
            {
                fract = BigInteger.One.ShiftLeft(scale).Subtract(fract);
            }

            if ((floorBigInt.SignValue == -1) && (!(fract.Equals(BigInteger.Zero))))
            {
                floorBigInt = floorBigInt.Add(BigInteger.One);
            }
            string leftOfPoint = floorBigInt.ToString();

            char[] fractCharArr = new char[scale];
            string fractStr     = fract.ToString(2);
            int    fractLen     = fractStr.Length;
            int    zeroes       = scale - fractLen;

            for (int i = 0; i < zeroes; i++)
            {
                fractCharArr[i] = '0';
            }
            for (int j = 0; j < fractLen; j++)
            {
                fractCharArr[zeroes + j] = fractStr[j];
            }
            string rightOfPoint = new string(fractCharArr);

            StringBuilder sb = new StringBuilder(leftOfPoint);

            sb.Append(".");
            sb.Append(rightOfPoint);

            return(sb.ToString());
        }
        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()));
            }
        }
Exemplo n.º 8
0
        /**
         * Computes the integer x that is expressed through the given primes and the
         * congruences with the chinese remainder theorem (CRT).
         *
         * @param congruences
         *            the congruences c_i
         * @param primes
         *            the primes p_i
         * @return an integer x for that x % p_i == c_i
         */
        private static IBigInteger chineseRemainder(IList congruences, IList primes)
        {
            IBigInteger retval = BigInteger.Zero;
            IBigInteger all    = BigInteger.One;

            for (int i = 0; i < primes.Count; i++)
            {
                all = all.Multiply((BigInteger)primes[i]);
            }
            for (int i = 0; i < primes.Count; i++)
            {
                IBigInteger a   = (BigInteger)primes[i];
                IBigInteger b   = all.Divide(a);
                IBigInteger b2  = b.ModInverse(a);
                IBigInteger tmp = b.Multiply(b2);
                tmp    = tmp.Multiply((BigInteger)congruences[i]);
                retval = retval.Add(tmp);
            }

            return(retval.Mod(all));
        }
Exemplo n.º 9
0
        /**
         * Approximate division by <code>n</code>. For an integer
         * <code>k</code>, the value <code>&#955; = s k / n</code> is
         * computed to <code>c</code> bits of accuracy.
         * @param k The parameter <code>k</code>.
         * @param s The curve parameter <code>s<sub>0</sub></code> or
         * <code>s<sub>1</sub></code>.
         * @param vm The Lucas Sequence element <code>V<sub>m</sub></code>.
         * @param a The parameter <code>a</code> of the elliptic curve.
         * @param m The bit length of the finite field
         * <code><b>F</b><sub>m</sub></code>.
         * @param c The number of bits of accuracy, i.e. the scale of the returned
         * <code>SimpleBigDecimal</code>.
         * @return The value <code>&#955; = s k / n</code> computed to
         * <code>c</code> bits of accuracy.
         */
        public static SimpleBigDecimal ApproximateDivisionByN(IBigInteger k,
                                                              IBigInteger s, IBigInteger vm, sbyte a, int m, int c)
        {
            int         _k = (m + 5) / 2 + c;
            IBigInteger ns = k.ShiftRight(m - _k - 2 + a);

            IBigInteger gs = s.Multiply(ns);

            IBigInteger hs = gs.ShiftRight(m);

            IBigInteger js = vm.Multiply(hs);

            IBigInteger gsPlusJs = gs.Add(js);
            IBigInteger ls       = gsPlusJs.ShiftRight(_k - c);

            if (gsPlusJs.TestBit(_k - c - 1))
            {
                // round up
                ls = ls.Add(BigInteger.One);
            }

            return(new SimpleBigDecimal(ls, c));
        }
        //Procedure B
        private void procedure_B(int x0, int c, IBigInteger[] pq)
        {
            //Verify and perform condition: 0<x<2^16; 0<c<2^16; c - odd.
            while (x0 < 0 || x0 > 65536)
            {
                x0 = init_random.NextInt() / 32768;
            }

            while ((c < 0 || c > 65536) || (c / 2 == 0))
            {
                c = init_random.NextInt() / 32768 + 1;
            }

            IBigInteger [] qp = new BigInteger[2];
            IBigInteger    q = null, Q = null, p = null;
            IBigInteger    C        = BigInteger.ValueOf(c);
            IBigInteger    constA16 = BigInteger.ValueOf(19381);

            //step1
            x0 = procedure_A(x0, c, qp, 256);
            q  = qp[0];

            //step2
            x0 = procedure_A(x0, c, qp, 512);
            Q  = qp[0];

            IBigInteger[] y = new IBigInteger[65];
            y[0] = BigInteger.ValueOf(x0);

            const int tp = 1024;

            IBigInteger qQ = q.Multiply(Q);

step3:
            for (;;)
            {
                //step 3
                for (int j = 0; j < 64; j++)
                {
                    y[j + 1] = (y[j].Multiply(constA16).Add(C)).Mod(BigInteger.Two.Pow(16));
                }

                //step 4
                IBigInteger Y = BigInteger.Zero;

                for (int j = 0; j < 64; j++)
                {
                    Y = Y.Add(y[j].ShiftLeft(16 * j));
                }

                y[0] = y[64];                 //step 5

                //step 6
                IBigInteger N = BigInteger.One.ShiftLeft(tp - 1).Divide(qQ).Add(
                    Y.ShiftLeft(tp - 1).Divide(qQ.ShiftLeft(1024)));

                if (N.TestBit(0))
                {
                    N = N.Add(BigInteger.One);
                }

                //step 7

                for (;;)
                {
                    //step 11
                    IBigInteger qQN = qQ.Multiply(N);

                    if (qQN.BitLength > tp)
                    {
                        goto step3;                         //step 9
                    }

                    p = qQN.Add(BigInteger.One);

                    //step10
                    if (BigInteger.Two.ModPow(qQN, p).CompareTo(BigInteger.One) == 0 &&
                        BigInteger.Two.ModPow(q.Multiply(N), p).CompareTo(BigInteger.One) != 0)
                    {
                        pq[0] = p;
                        pq[1] = q;
                        return;
                    }

                    N = N.Add(BigInteger.Two);
                }
            }
        }
 public SimpleBigDecimal Add(SimpleBigDecimal b)
 {
     CheckScale(b);
     return(new SimpleBigDecimal(bigInt.Add(b.bigInt), scale));
 }
        public IBigInteger And(
            IBigInteger value)
        {
            if (this.SignValue == 0 || value.SignValue == 0)
            {
                return Zero;
            }

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

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

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

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

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

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

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

                resultMag[i] = aWord & bWord;

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

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

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

            return result;
        }
Exemplo n.º 13
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);
        }
Exemplo n.º 14
0
        /**
         * Fetches delta CRLs according to RFC 3280 section 5.2.4.
         *
         * @param currentDate The date for which the delta CRLs must be valid.
         * @param paramsPKIX The extended PKIX parameters.
         * @param completeCRL The complete CRL the delta CRL is for.
         * @return A <code>Set</code> of <code>X509CRL</code>s with delta CRLs.
         * @throws Exception if an exception occurs while picking the delta
         *             CRLs.
         */
        internal static ISet GetDeltaCrls(
            DateTime currentDate,
            PkixParameters paramsPKIX,
            X509Crl completeCRL)
        {
            X509CrlStoreSelector deltaSelect = new X509CrlStoreSelector();

            // 5.2.4 (a)
            try
            {
                IList deltaSelectIssuer = Platform.CreateArrayList();
                deltaSelectIssuer.Add(completeCRL.IssuerDN);
                deltaSelect.Issuers = deltaSelectIssuer;
            }
            catch (IOException e)
            {
                new Exception("Cannot extract issuer from CRL.", e);
            }

            IBigInteger completeCRLNumber = null;

            try
            {
                Asn1Object asn1Object = GetExtensionValue(completeCRL, X509Extensions.CrlNumber);
                if (asn1Object != null)
                {
                    completeCRLNumber = CrlNumber.GetInstance(asn1Object).PositiveValue;
                }
            }
            catch (Exception e)
            {
                throw new Exception(
                          "CRL number extension could not be extracted from CRL.", e);
            }

            // 5.2.4 (b)
            byte[] idp = null;

            try
            {
                Asn1Object obj = GetExtensionValue(completeCRL, X509Extensions.IssuingDistributionPoint);
                if (obj != null)
                {
                    idp = obj.GetDerEncoded();
                }
            }
            catch (Exception e)
            {
                throw new Exception(
                          "Issuing distribution point extension value could not be read.",
                          e);
            }

            // 5.2.4 (d)

            deltaSelect.MinCrlNumber = (completeCRLNumber == null)
                                ?       null
                                :       completeCRLNumber.Add(BigInteger.One);

            deltaSelect.IssuingDistributionPoint        = idp;
            deltaSelect.IssuingDistributionPointEnabled = true;

            // 5.2.4 (c)
            deltaSelect.MaxBaseCrlNumber = completeCRLNumber;

            // find delta CRLs
            ISet temp = CrlUtilities.FindCrls(deltaSelect, paramsPKIX, currentDate);

            ISet result = new HashSet();

            foreach (X509Crl crl in temp)
            {
                if (isDeltaCrl(crl))
                {
                    result.Add(crl);
                }
            }

            return(result);
        }
        //Procedure B'
        private void procedure_Bb(long x0, long c, IBigInteger[] pq)
        {
            //Verify and perform condition: 0<x<2^32; 0<c<2^32; c - odd.
            while (x0 < 0 || x0 > 4294967296L)
            {
                x0 = init_random.NextInt() * 2;
            }

            while ((c < 0 || c > 4294967296L) || (c / 2 == 0))
            {
                c = init_random.NextInt() * 2 + 1;
            }

            IBigInteger [] qp = new BigInteger[2];
            IBigInteger    q = null, Q = null, p = null;
            IBigInteger    C        = BigInteger.ValueOf(c);
            IBigInteger    constA32 = BigInteger.ValueOf(97781173);

            //step1
            x0 = procedure_Aa(x0, c, qp, 256);
            q  = qp[0];

            //step2
            x0 = procedure_Aa(x0, c, qp, 512);
            Q  = qp[0];

            IBigInteger[] y = new IBigInteger[33];
            y[0] = BigInteger.ValueOf(x0);

            const int tp = 1024;

            IBigInteger qQ = q.Multiply(Q);

step3:
            for (;;)
            {
                //step 3
                for (int j = 0; j < 32; j++)
                {
                    y[j + 1] = (y[j].Multiply(constA32).Add(C)).Mod(BigInteger.Two.Pow(32));
                }

                //step 4
                IBigInteger Y = BigInteger.Zero;
                for (int j = 0; j < 32; j++)
                {
                    Y = Y.Add(y[j].ShiftLeft(32 * j));
                }

                y[0] = y[32];                 //step 5

                //step 6
                IBigInteger N = BigInteger.One.ShiftLeft(tp - 1).Divide(qQ).Add(
                    Y.ShiftLeft(tp - 1).Divide(qQ.ShiftLeft(1024)));

                if (N.TestBit(0))
                {
                    N = N.Add(BigInteger.One);
                }

                //step 7

                for (;;)
                {
                    //step 11
                    IBigInteger qQN = qQ.Multiply(N);

                    if (qQN.BitLength > tp)
                    {
                        goto step3;                         //step 9
                    }

                    p = qQN.Add(BigInteger.One);

                    //step10
                    if (BigInteger.Two.ModPow(qQN, p).CompareTo(BigInteger.One) == 0 &&
                        BigInteger.Two.ModPow(q.Multiply(N), p).CompareTo(BigInteger.One) != 0)
                    {
                        pq[0] = p;
                        pq[1] = q;
                        return;
                    }

                    N = N.Add(BigInteger.Two);
                }
            }
        }
Exemplo n.º 16
0
        /**
         * Rounds an element <code>&#955;</code> of <code><b>R</b>[&#964;]</code>
         * to an element of <code><b>Z</b>[&#964;]</code>, such that their difference
         * has minimal norm. <code>&#955;</code> is given as
         * <code>&#955; = &#955;<sub>0</sub> + &#955;<sub>1</sub>&#964;</code>.
         * @param lambda0 The component <code>&#955;<sub>0</sub></code>.
         * @param lambda1 The component <code>&#955;<sub>1</sub></code>.
         * @param mu The parameter <code>&#956;</code> of the elliptic curve. Must
         * equal 1 or -1.
         * @return The rounded element of <code><b>Z</b>[&#964;]</code>.
         * @throws ArgumentException if <code>lambda0</code> and
         * <code>lambda1</code> do not have same scale.
         */
        public static ZTauElement Round(SimpleBigDecimal lambda0,
                                        SimpleBigDecimal lambda1, sbyte mu)
        {
            int scale = lambda0.Scale;

            if (lambda1.Scale != scale)
            {
                throw new ArgumentException("lambda0 and lambda1 do not have same scale");
            }

            if (!((mu == 1) || (mu == -1)))
            {
                throw new ArgumentException("mu must be 1 or -1");
            }

            IBigInteger f0 = lambda0.Round();
            IBigInteger f1 = lambda1.Round();

            SimpleBigDecimal eta0 = lambda0.Subtract(f0);
            SimpleBigDecimal eta1 = lambda1.Subtract(f1);

            // eta = 2*eta0 + mu*eta1
            SimpleBigDecimal eta = eta0.Add(eta0);

            if (mu == 1)
            {
                eta = eta.Add(eta1);
            }
            else
            {
                // mu == -1
                eta = eta.Subtract(eta1);
            }

            // check1 = eta0 - 3*mu*eta1
            // check2 = eta0 + 4*mu*eta1
            SimpleBigDecimal threeEta1 = eta1.Add(eta1).Add(eta1);
            SimpleBigDecimal fourEta1  = threeEta1.Add(eta1);
            SimpleBigDecimal check1;
            SimpleBigDecimal check2;

            if (mu == 1)
            {
                check1 = eta0.Subtract(threeEta1);
                check2 = eta0.Add(fourEta1);
            }
            else
            {
                // mu == -1
                check1 = eta0.Add(threeEta1);
                check2 = eta0.Subtract(fourEta1);
            }

            sbyte h0 = 0;
            sbyte h1 = 0;

            // if eta >= 1
            if (eta.CompareTo(BigInteger.One) >= 0)
            {
                if (check1.CompareTo(MinusOne) < 0)
                {
                    h1 = mu;
                }
                else
                {
                    h0 = 1;
                }
            }
            else
            {
                // eta < 1
                if (check2.CompareTo(BigInteger.Two) >= 0)
                {
                    h1 = mu;
                }
            }

            // if eta < -1
            if (eta.CompareTo(MinusOne) < 0)
            {
                if (check1.CompareTo(BigInteger.One) >= 0)
                {
                    h1 = (sbyte)-mu;
                }
                else
                {
                    h0 = -1;
                }
            }
            else
            {
                // eta >= -1
                if (check2.CompareTo(MinusTwo) < 0)
                {
                    h1 = (sbyte)-mu;
                }
            }

            IBigInteger q0 = f0.Add(BigInteger.ValueOf(h0));
            IBigInteger q1 = f1.Add(BigInteger.ValueOf(h1));

            return(new ZTauElement(q0, q1));
        }
Exemplo n.º 17
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);
        }
        //Procedure A
        private int procedure_A(int x0, int c, IBigInteger[] pq, int size)
        {
            //Verify and perform condition: 0<x<2^16; 0<c<2^16; c - odd.
            while (x0 < 0 || x0 > 65536)
            {
                x0 = init_random.NextInt() / 32768;
            }

            while ((c < 0 || c > 65536) || (c / 2 == 0))
            {
                c = init_random.NextInt() / 32768 + 1;
            }

            IBigInteger C        = BigInteger.ValueOf(c);
            IBigInteger constA16 = BigInteger.ValueOf(19381);

            //step1
            IBigInteger[] y = new IBigInteger[1];             // begin length = 1
            y[0] = BigInteger.ValueOf(x0);

            //step 2
            int[] t = new int[1];             // t - orders; begin length = 1
            t[0] = size;
            int s = 0;

            for (int i = 0; t[i] >= 17; i++)
            {
                // extension array t
                int[] tmp_t = new int[t.Length + 1];                       ///////////////
                Array.Copy(t, 0, tmp_t, 0, t.Length);                      //  extension
                t = new int[tmp_t.Length];                                 //  array t
                Array.Copy(tmp_t, 0, t, 0, tmp_t.Length);                  ///////////////

                t[i + 1] = t[i] / 2;
                s        = i + 1;
            }

            //step3
            IBigInteger[] p = new IBigInteger[s + 1];
            p[s] = new BigInteger("8003", 16); //set min prime number length 16 bit

            int m = s - 1;                     //step4

            for (int i = 0; i < s; i++)
            {
                int rm = t[m] / 16;                //step5

                step6 : for (;;)
                {
                    //step 6
                    IBigInteger[] tmp_y = new BigInteger[y.Length];                  ////////////////
                    Array.Copy(y, 0, tmp_y, 0, y.Length);                            //  extension
                    y = new BigInteger[rm + 1];                                      //  array y
                    Array.Copy(tmp_y, 0, y, 0, tmp_y.Length);                        ////////////////

                    for (int j = 0; j < rm; j++)
                    {
                        y[j + 1] = (y[j].Multiply(constA16).Add(C)).Mod(BigInteger.Two.Pow(16));
                    }

                    //step 7
                    IBigInteger Ym = BigInteger.Zero;
                    for (int j = 0; j < rm; j++)
                    {
                        Ym = Ym.Add(y[j].ShiftLeft(16 * j));
                    }

                    y[0] = y[rm];                        //step 8

                    //step 9
                    IBigInteger N = BigInteger.One.ShiftLeft(t[m] - 1).Divide(p[m + 1]).Add(
                        Ym.ShiftLeft(t[m] - 1).Divide(p[m + 1].ShiftLeft(16 * rm)));

                    if (N.TestBit(0))
                    {
                        N = N.Add(BigInteger.One);
                    }

                    //step 10

                    for (;;)
                    {
                        //step 11
                        IBigInteger NByLastP = N.Multiply(p[m + 1]);

                        if (NByLastP.BitLength > t[m])
                        {
                            goto step6;                                     //step 12
                        }

                        p[m] = NByLastP.Add(BigInteger.One);

                        //step13
                        if (BigInteger.Two.ModPow(NByLastP, p[m]).CompareTo(BigInteger.One) == 0 &&
                            BigInteger.Two.ModPow(N, p[m]).CompareTo(BigInteger.One) != 0)
                        {
                            break;
                        }

                        N = N.Add(BigInteger.Two);
                    }

                    if (--m < 0)
                    {
                        pq[0] = p[0];
                        pq[1] = p[1];
                        return(y[0].IntValue);                           //return for procedure B step 2
                    }

                    break;                        //step 14
                }
            }
            return(y[0].IntValue);
        }
        /**
         * generate suitable parameters for DSA, in line with
         * <i>FIPS 186-3 A.1 Generation of the FFC Primes p and q</i>.
         */
        private DsaParameters GenerateParameters_FIPS186_3()
        {
// A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function
            // FIXME This should be configurable (digest size in bits must be >= N)
            IDigest d      = new Sha256Digest();
            int     outlen = d.GetDigestSize() * 8;

// 1. Check that the (L, N) pair is in the list of acceptable (L, N pairs) (see Section 4.2). If
//    the pair is not in the list, then return INVALID.
            // Note: checked at initialisation

// 2. If (seedlen < N), then return INVALID.
            // FIXME This should be configurable (must be >= N)
            int seedlen = N;

            byte[] seed = new byte[seedlen / 8];

// 3. n = ceiling(L ⁄ outlen) – 1.
            int n = (L - 1) / outlen;

// 4. b = L – 1 – (n ∗ outlen).
            int b = (L - 1) % outlen;

            byte[] output = new byte[d.GetDigestSize()];
            for (;;)
            {
// 5. Get an arbitrary sequence of seedlen bits as the domain_parameter_seed.
                random.NextBytes(seed);

// 6. U = Hash (domain_parameter_seed) mod 2^(N–1).
                Hash(d, seed, output);
                IBigInteger U = new BigInteger(1, output).Mod(BigInteger.One.ShiftLeft(N - 1));

// 7. q = 2^(N–1) + U + 1 – ( U mod 2).
                IBigInteger q = BigInteger.One.ShiftLeft(N - 1).Add(U).Add(BigInteger.One).Subtract(
                    U.Mod(BigInteger.Two));

// 8. Test whether or not q is prime as specified in Appendix C.3.
                // TODO Review C.3 for primality checking
                if (!q.IsProbablePrime(certainty))
                {
// 9. If q is not a prime, then go to step 5.
                    continue;
                }

// 10. offset = 1.
                // Note: 'offset' value managed incrementally
                byte[] offset = Arrays.Clone(seed);

// 11. For counter = 0 to (4L – 1) do
                int counterLimit = 4 * L;
                for (int counter = 0; counter < counterLimit; ++counter)
                {
// 11.1 For j = 0 to n do
//      Vj = Hash ((domain_parameter_seed + offset + j) mod 2^seedlen).
// 11.2 W = V0 + (V1 ∗ 2^outlen) + ... + (V^(n–1) ∗ 2^((n–1) ∗ outlen)) + ((Vn mod 2^b) ∗ 2^(n ∗ outlen)).
                    // TODO Assemble w as a byte array
                    IBigInteger W = BigInteger.Zero;
                    for (int j = 0, exp = 0; j <= n; ++j, exp += outlen)
                    {
                        Inc(offset);
                        Hash(d, offset, output);

                        IBigInteger Vj = new BigInteger(1, output);
                        if (j == n)
                        {
                            Vj = Vj.Mod(BigInteger.One.ShiftLeft(b));
                        }

                        W = W.Add(Vj.ShiftLeft(exp));
                    }

// 11.3 X = W + 2^(L–1). Comment: 0 ≤ W < 2L–1; hence, 2L–1 ≤ X < 2L.
                    IBigInteger X = W.Add(BigInteger.One.ShiftLeft(L - 1));

// 11.4 c = X mod 2q.
                    IBigInteger c = X.Mod(q.ShiftLeft(1));

// 11.5 p = X - (c - 1). Comment: p ≡ 1 (mod 2q).
                    IBigInteger p = X.Subtract(c.Subtract(BigInteger.One));

                    // 11.6 If (p < 2^(L - 1)), then go to step 11.9
                    if (p.BitLength != L)
                    {
                        continue;
                    }

// 11.7 Test whether or not p is prime as specified in Appendix C.3.
                    // TODO Review C.3 for primality checking
                    if (p.IsProbablePrime(certainty))
                    {
// 11.8 If p is determined to be prime, then return VALID and the values of p, q and
//      (optionally) the values of domain_parameter_seed and counter.
                        // TODO Make configurable (8-bit unsigned)?
//	                    int index = 1;
//	                    IBigInteger g = CalculateGenerator_FIPS186_3_Verifiable(d, p, q, seed, index);
//	                    if (g != null)
//	                    {
//	                        // TODO Should 'index' be a part of the validation parameters?
//	                        return new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter));
//	                    }

                        IBigInteger g = CalculateGenerator_FIPS186_3_Unverifiable(p, q, random);
                        return(new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter)));
                    }

// 11.9 offset = offset + n + 1.      Comment: Increment offset; then, as part of
//                                    the loop in step 11, increment counter; if
//                                    counter < 4L, repeat steps 11.1 through 11.8.
                    // Note: 'offset' value already incremented in inner loop
                }
// 12. Go to step 5.
            }
        }