Beispiel #1
0
        public void TestECBasicAgreementTest()
        {
            var random = new SecureRandom();

            var curve = new FPCurve(
                new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q
                new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16),         // a
                new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16));        // b

            var parameters = new ECDomainParameters(
                curve,
                curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
                new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"));     // n


            var pGen     = new ECKeyPairGenerator();
            var genParam = new ECKeyGenerationParameters(parameters, random);

            pGen.Init(genParam);

            IAsymmetricCipherKeyPair p1 = pGen.GenerateKeyPair();
            IAsymmetricCipherKeyPair p2 = pGen.GenerateKeyPair();

            //
            // two way
            //
            IBasicAgreement e1 = new ECDHBasicAgreement();
            IBasicAgreement e2 = new ECDHBasicAgreement();

            e1.Init(p1.Private);
            e2.Init(p2.Private);

            IBigInteger k1 = e1.CalculateAgreement(p2.Public);
            IBigInteger k2 = e2.CalculateAgreement(p1.Public);

            if (!k1.Equals(k2))
            {
                Fail("calculated agreement test failed");
            }

            //
            // two way
            //
            e1 = new ECDHCBasicAgreement();
            e2 = new ECDHCBasicAgreement();

            e1.Init(p1.Private);
            e2.Init(p2.Private);

            k1 = e1.CalculateAgreement(p2.Public);
            k2 = e2.CalculateAgreement(p1.Public);

            if (!k1.Equals(k2))
            {
                Fail("calculated agreement test failed");
            }
        }
Beispiel #2
0
        private void testMutualVerification(IBigInteger N, IBigInteger g)
        {
            byte[] I = Encoding.UTF8.GetBytes("username");
            byte[] P = Encoding.UTF8.GetBytes("password");
            byte[] s = new byte[16];
            random.NextBytes(s);

            Srp6VerifierGenerator gen = new Srp6VerifierGenerator();

            gen.Init(N, g, new Sha256Digest());
            IBigInteger v = gen.GenerateVerifier(s, I, P);

            Srp6Client client = new Srp6Client();

            client.Init(N, g, new Sha256Digest(), random);

            Srp6Server server = new Srp6Server();

            server.Init(N, g, v, new Sha256Digest(), random);

            IBigInteger A = client.GenerateClientCredentials(s, I, P);
            IBigInteger B = server.GenerateServerCredentials();

            IBigInteger clientS = client.CalculateSecret(B);
            IBigInteger serverS = server.CalculateSecret(A);

            if (!clientS.Equals(serverS))
            {
                Fail("SRP agreement failed - client/server calculated different secrets");
            }
        }
Beispiel #3
0
        public void DecodeTest()
        {
//			EllipticCurve curve = new EllipticCurve(
//				new ECFieldFp(new BigInteger("6277101735386680763835789423207666416083908700390324961279")), // q
//				new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a
//				new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b
            ECCurve curve = new FPCurve(
                new BigInteger("6277101735386680763835789423207666416083908700390324961279"),           // q
                new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16),                 // a
                new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16));                // b

//			ECPoint p = ECPointUtil.DecodePoint(curve, Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012"));
            ECPoint p = curve.DecodePoint(Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012"));

            IBigInteger x = p.X.ToBigInteger();             //p.getAffineX();

            if (!x.Equals(new BigInteger("188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", 16)))
            {
                Fail("x uncompressed incorrectly");
            }

            IBigInteger y = p.Y.ToBigInteger();             //p.getAffineX();

            if (!y.Equals(new BigInteger("7192b95ffc8da78631011ed6b24cdd573f977a11e794811", 16)))
            {
                Fail("y uncompressed incorrectly");
            }
        }
 protected bool Equals(
     DHParameters other)
 {
     return(p.Equals(other.p) &&
            g.Equals(other.g) &&
            Platform.Equals(q, other.q));
 }
Beispiel #5
0
        /**
         * X9.62 - 1998,<br/>
         * J.3.1, Page 152, ECDSA over the field Fp<br/>
         * an example with 192 bit prime
         */

        private static IBigInteger CalculateAgreement(
            IAsymmetricCipherKeyPair u1,
            IAsymmetricCipherKeyPair u2,
            IAsymmetricCipherKeyPair v1,
            IAsymmetricCipherKeyPair v2)
        {
            var u = new ECMqvBasicAgreement();

            u.Init(new MqvPrivateParameters(
                       (ECPrivateKeyParameters)u1.Private,
                       (ECPrivateKeyParameters)u2.Private,
                       (ECPublicKeyParameters)u2.Public));
            IBigInteger ux = u.CalculateAgreement(new MqvPublicParameters(
                                                      (ECPublicKeyParameters)v1.Public,
                                                      (ECPublicKeyParameters)v2.Public));

            var v = new ECMqvBasicAgreement();

            v.Init(new MqvPrivateParameters(
                       (ECPrivateKeyParameters)v1.Private,
                       (ECPrivateKeyParameters)v2.Private,
                       (ECPublicKeyParameters)v2.Public));
            IBigInteger vx = v.CalculateAgreement(new MqvPublicParameters(
                                                      (ECPublicKeyParameters)u1.Public,
                                                      (ECPublicKeyParameters)u2.Public));

            if (ux.Equals(vx))
            {
                return(ux);
            }

            return(null);
        }
 protected bool Equals(ECDomainParameters other)
 {
     return(_curve.Equals(other.Curve) &&
            _g.Equals(other.G) &&
            _n.Equals(other.N) &&
            _h.Equals(other.H) &&
            Arrays.AreEqual(_seed, other._seed));
 }
Beispiel #7
0
        /**
         * this test is can take quiet a while
         */
        private void doTestGeneration(
            int size)
        {
            DHParametersGenerator pGen = new DHParametersGenerator();

            pGen.Init(size, 10, new SecureRandom());

            DHParameters dhParams = pGen.GenerateParameters();

            if (dhParams.L != 0)
            {
                Fail("DHParametersGenerator failed to set J to 0 in generated DHParameters");
            }

            DHKeyGenerationParameters dhkgParams = new DHKeyGenerationParameters(new SecureRandom(), dhParams);

            DHBasicKeyPairGenerator kpGen = new DHBasicKeyPairGenerator();

            kpGen.Init(dhkgParams);

            //
            // generate first pair
            //
            IAsymmetricCipherKeyPair pair = kpGen.GenerateKeyPair();

            DHPublicKeyParameters  pu1 = (DHPublicKeyParameters)pair.Public;
            DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters)pair.Private;

            //
            // generate second pair
            //
            dhkgParams = new DHKeyGenerationParameters(new SecureRandom(), pu1.Parameters);

            kpGen.Init(dhkgParams);

            pair = kpGen.GenerateKeyPair();

            DHPublicKeyParameters  pu2 = (DHPublicKeyParameters)pair.Public;
            DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters)pair.Private;

            //
            // two way
            //
            DHBasicAgreement e1 = new DHBasicAgreement();
            DHBasicAgreement e2 = new DHBasicAgreement();

            e1.Init(new ParametersWithRandom(pv1, new SecureRandom()));
            e2.Init(new ParametersWithRandom(pv2, new SecureRandom()));

            IBigInteger k1 = e1.CalculateAgreement(pu2);
            IBigInteger k2 = e2.CalculateAgreement(pu1);

            if (!k1.Equals(k2))
            {
                Fail("basic with " + size + " bit 2-way test failed");
            }
        }
        public static IBigInteger ValidatePublicValue(IBigInteger N, IBigInteger val)
        {
            val = val.Mod(N);

            // Check that val % N != 0
            if (val.Equals(BigInteger.Zero))
                throw new CryptoException("Invalid public value: 0");

            return val;
        }
        /**
         * <pre>
         * MacData ::= SEQUENCE {
         *     mac      DigestInfo,
         *     macSalt  OCTET STRING,
         *     iterations INTEGER DEFAULT 1
         *     -- Note: The default is for historic reasons and its use is deprecated. A
         *     -- higher value, like 1024 is recommended.
         * </pre>
         * @return the basic DERObject construction.
         */
        public override Asn1Object ToAsn1Object()
        {
            Asn1EncodableVector v = new Asn1EncodableVector(digInfo, new DerOctetString(salt));

            if (!iterationCount.Equals(BigInteger.One))
            {
                v.Add(new DerInteger(iterationCount));
            }

            return(new DerSequence(v));
        }
        public override bool Equals(object obj)
        {
            var other = obj as RsaKeyGenerationParameters;

            if (other == null)
            {
                return(false);
            }
            return(_certainty == other._certainty &&
                   _publicExponent.Equals(other._publicExponent));
        }
        public static IBigInteger ValidatePublicValue(IBigInteger N, IBigInteger val)
        {
            val = val.Mod(N);

            // Check that val % N != 0
            if (val.Equals(BigInteger.Zero))
            {
                throw new CryptoException("Invalid public value: 0");
            }

            return(val);
        }
Beispiel #12
0
        private void doTestExplicitWrapping(
            int size,
            int privateValueSize,
            IBigInteger g,
            IBigInteger p)
        {
            DHParameters dhParams = new DHParameters(p, g, null, privateValueSize);

            IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("DH");

            keyGen.Init(new DHKeyGenerationParameters(new SecureRandom(), dhParams));

            //
            // a side
            //
            IAsymmetricCipherKeyPair aKeyPair = keyGen.GenerateKeyPair();

            IBasicAgreement aKeyAgree = AgreementUtilities.GetBasicAgreement("DH");

            checkKeySize(privateValueSize, aKeyPair);

            aKeyAgree.Init(aKeyPair.Private);

            //
            // b side
            //
            IAsymmetricCipherKeyPair bKeyPair = keyGen.GenerateKeyPair();

            IBasicAgreement bKeyAgree = AgreementUtilities.GetBasicAgreement("DH");

            checkKeySize(privateValueSize, bKeyPair);

            bKeyAgree.Init(bKeyPair.Private);

            //
            // agreement
            //
//			aKeyAgree.doPhase(bKeyPair.Public, true);
//			bKeyAgree.doPhase(aKeyPair.Public, true);
//
//			SecretKey k1 = aKeyAgree.generateSecret(PkcsObjectIdentifiers.IdAlgCms3DesWrap.Id);
//			SecretKey k2 = bKeyAgree.generateSecret(PkcsObjectIdentifiers.IdAlgCms3DesWrap.Id);

            // TODO Does this really test the same thing as the above code?
            IBigInteger b1 = aKeyAgree.CalculateAgreement(bKeyPair.Public);
            IBigInteger b2 = bKeyAgree.CalculateAgreement(aKeyPair.Public);

            if (!b1.Equals(b2))
            {
                Fail("Explicit wrapping test failed");
            }
        }
 protected void checkOptionalField(string name, IBigInteger expected, IBigInteger present)
 {
     if (expected != null)
     {
         if (!expected.Equals(present))
         {
             Fail(name + " field doesn't match.");
         }
     }
     else if (present != null)
     {
         Fail(name + " field found when none expected.");
     }
 }
Beispiel #14
0
 protected void checkOptionalField(string name, IBigInteger expected, IBigInteger present)
 {
     if (expected != null)
     {
         if (!expected.Equals(present))
         {
             Fail(name + " field doesn't match.");
         }
     }
     else if (present != null)
     {
         Fail(name + " field found when none expected.");
     }
 }
        // 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));
        }
Beispiel #16
0
        private void ecNR239bitPrime()
        {
            FPCurve curve = new FPCurve(
                new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),         // q
                new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16),                 // a
                new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16));                // b

            ECDomainParameters parameters = new ECDomainParameters(
                curve,
                curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")),             // G
                new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"));                 // n

            ECPrivateKeyParameters priKey = new ECPrivateKeyParameters(
                new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"),                 // d
                parameters);

            ECNRSigner           ecnr  = new ECNRSigner();
            ParametersWithRandom param = new ParametersWithRandom(priKey, k);

            ecnr.Init(true, param);

            byte[]        message = new BigInteger("968236873715988614170569073515315707566766479517").ToByteArray();
            IBigInteger[] sig     = ecnr.GenerateSignature(message);

            if (!r.Equals(sig[0]))
            {
                Fail("r component wrong.", r, sig[0]);
            }

            if (!s.Equals(sig[1]))
            {
                Fail("s component wrong.", s, sig[1]);
            }

            // Verify the signature
            ECPublicKeyParameters pubKey = new ECPublicKeyParameters(
                curve.DecodePoint(Hex.Decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")),                 // Q
                parameters);

            ecnr.Init(false, pubKey);
            if (!ecnr.VerifySignature(message, sig[0], sig[1]))
            {
                Fail("signature fails");
            }
        }
        public override bool Equals(
            object obj)
        {
            if (this == obj)
            {
                return(true);
            }

            SimpleBigDecimal other = obj as SimpleBigDecimal;

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

            return(bigInt.Equals(other.bigInt) &&
                   scale == other.scale);
        }
        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());
        }
Beispiel #19
0
        private void doTestDHBasic(
            int size,
            int privateValueSize,
            IBigInteger g,
            IBigInteger p)
        {
            DHBasicKeyPairGenerator kpGen = getDHBasicKeyPairGenerator(g, p, privateValueSize);

            //
            // generate first pair
            //
            IAsymmetricCipherKeyPair pair = kpGen.GenerateKeyPair();

            DHPublicKeyParameters  pu1 = (DHPublicKeyParameters)pair.Public;
            DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters)pair.Private;

            checkKeySize(privateValueSize, pv1);
            //
            // generate second pair
            //
            pair = kpGen.GenerateKeyPair();

            DHPublicKeyParameters  pu2 = (DHPublicKeyParameters)pair.Public;
            DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters)pair.Private;

            checkKeySize(privateValueSize, pv2);
            //
            // two way
            //
            DHBasicAgreement e1 = new DHBasicAgreement();
            DHBasicAgreement e2 = new DHBasicAgreement();

            e1.Init(pv1);
            e2.Init(pv2);

            IBigInteger k1 = e1.CalculateAgreement(pu2);
            IBigInteger k2 = e2.CalculateAgreement(pu1);

            if (!k1.Equals(k2))
            {
                Fail("basic " + size + " bit 2-way test failed");
            }
        }
Beispiel #20
0
        private void doTestDH(
            int size,
            IBigInteger g,
            IBigInteger p)
        {
            DHKeyPairGenerator kpGen = getDHKeyPairGenerator(g, p);

            //
            // generate first pair
            //
            IAsymmetricCipherKeyPair pair = kpGen.GenerateKeyPair();

            DHPublicKeyParameters  pu1 = (DHPublicKeyParameters)pair.Public;
            DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters)pair.Private;

            //
            // generate second pair
            //
            pair = kpGen.GenerateKeyPair();

            DHPublicKeyParameters  pu2 = (DHPublicKeyParameters)pair.Public;
            DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters)pair.Private;

            //
            // two way
            //
            DHAgreement e1 = new DHAgreement();
            DHAgreement e2 = new DHAgreement();

            e1.Init(pv1);
            e2.Init(pv2);

            IBigInteger m1 = e1.CalculateMessage();
            IBigInteger m2 = e2.CalculateMessage();

            IBigInteger k1 = e1.CalculateAgreement(pu2, m2);
            IBigInteger k2 = e2.CalculateAgreement(pu1, m1);

            if (!k1.Equals(k2))
            {
                Fail(size + " bit 2-way test failed");
            }
        }
        private void checkSignature(
            int size,
            ECPrivateKeyParameters sKey,
            ECPublicKeyParameters vKey,
            ISigner sgr,
            SecureRandom k,
            byte[]                                  message,
            IBigInteger r,
            IBigInteger s)
        {
            sgr.Init(true, new ParametersWithRandom(sKey, k));

            sgr.BlockUpdate(message, 0, message.Length);

            byte[] sigBytes = sgr.GenerateSignature();

            sgr.Init(false, vKey);

            sgr.BlockUpdate(message, 0, message.Length);

            if (!sgr.VerifySignature(sigBytes))
            {
                Fail(size + " bit EC verification failed");
            }

            IBigInteger[] sig = derDecode(sigBytes);

            if (!r.Equals(sig[0]))
            {
                Fail(size + "bit"
                     + ": r component wrong." + SimpleTest.NewLine
                     + " expecting: " + r + SimpleTest.NewLine
                     + " got      : " + sig[0]);
            }

            if (!s.Equals(sig[1]))
            {
                Fail(size + "bit"
                     + ": s component wrong." + SimpleTest.NewLine
                     + " expecting: " + s + SimpleTest.NewLine
                     + " got      : " + sig[1]);
            }
        }
Beispiel #22
0
        /**
         * Returns the parameter <code>&#956;</code> of the elliptic curve.
         * @param curve The elliptic curve from which to obtain <code>&#956;</code>.
         * The curve must be a Koblitz curve, i.e. <code>a</code> Equals
         * <code>0</code> or <code>1</code> and <code>b</code> Equals
         * <code>1</code>.
         * @return <code>&#956;</code> of the elliptic curve.
         * @throws ArgumentException if the given ECCurve is not a Koblitz
         * curve.
         */
        public static sbyte GetMu(F2MCurve curve)
        {
            IBigInteger a = curve.A.ToBigInteger();

            sbyte mu;

            if (a.SignValue == 0)
            {
                mu = -1;
            }
            else if (a.Equals(BigInteger.One))
            {
                mu = 1;
            }
            else
            {
                throw new ArgumentException("No Koblitz curve (ABC), TNAF multiplication not possible");
            }
            return(mu);
        }
Beispiel #23
0
        public virtual X509CrlEntry GetRevokedCertificate(
            IBigInteger serialNumber)
        {
            IEnumerable certs = c.GetRevokedCertificateEnumeration();

            X509Name previousCertificateIssuer = IssuerDN;

            foreach (CrlEntry entry in certs)
            {
                X509CrlEntry crlEntry = new X509CrlEntry(entry, isIndirect, previousCertificateIssuer);

                if (serialNumber.Equals(entry.UserCertificate.Value))
                {
                    return(crlEntry);
                }

                previousCertificateIssuer = crlEntry.GetCertificateIssuer();
            }

            return(null);
        }
Beispiel #24
0
        public void TestECMqvTestVector1()
        {
            // Test Vector from GEC-2

            X9ECParameters x9 = SecNamedCurves.GetByName("secp160r1");
            var            p  = new ECDomainParameters(
                x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed());

            IAsymmetricCipherKeyPair u1 = new AsymmetricCipherKeyPair(
                new ECPublicKeyParameters(
                    p.Curve.DecodePoint(Hex.Decode("0251B4496FECC406ED0E75A24A3C03206251419DC0")), p),
                new ECPrivateKeyParameters(
                    new BigInteger("AA374FFC3CE144E6B073307972CB6D57B2A4E982", 16), p));

            IAsymmetricCipherKeyPair u2 = new AsymmetricCipherKeyPair(
                new ECPublicKeyParameters(
                    p.Curve.DecodePoint(Hex.Decode("03D99CE4D8BF52FA20BD21A962C6556B0F71F4CA1F")), p),
                new ECPrivateKeyParameters(
                    new BigInteger("149EC7EA3A220A887619B3F9E5B4CA51C7D1779C", 16), p));

            IAsymmetricCipherKeyPair v1 = new AsymmetricCipherKeyPair(
                new ECPublicKeyParameters(
                    p.Curve.DecodePoint(Hex.Decode("0349B41E0E9C0369C2328739D90F63D56707C6E5BC")), p),
                new ECPrivateKeyParameters(
                    new BigInteger("45FB58A92A17AD4B15101C66E74F277E2B460866", 16), p));

            IAsymmetricCipherKeyPair v2 = new AsymmetricCipherKeyPair(
                new ECPublicKeyParameters(
                    p.Curve.DecodePoint(Hex.Decode("02706E5D6E1F640C6E9C804E75DBC14521B1E5F3B5")), p),
                new ECPrivateKeyParameters(
                    new BigInteger("18C13FCED9EADF884F7C595C8CB565DEFD0CB41E", 16), p));

            IBigInteger x = CalculateAgreement(u1, u2, v1, v2);

            if (x == null ||
                !x.Equals(new BigInteger("5A6955CEFDB4E43255FB7FCF718611E4DF8E05AC", 16)))
            {
                Fail("MQV Test Vector #1 agreement failed");
            }
        }
Beispiel #25
0
        public void TestECMqvTestVector2()
        {
            // Test Vector from GEC-2

            X9ECParameters x9 = SecNamedCurves.GetByName("sect163k1");
            var            p  = new ECDomainParameters(
                x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed());

            IAsymmetricCipherKeyPair u1 = new AsymmetricCipherKeyPair(
                new ECPublicKeyParameters(
                    p.Curve.DecodePoint(Hex.Decode("03037D529FA37E42195F10111127FFB2BB38644806BC")), p),
                new ECPrivateKeyParameters(
                    new BigInteger("03A41434AA99C2EF40C8495B2ED9739CB2155A1E0D", 16), p));

            IAsymmetricCipherKeyPair u2 = new AsymmetricCipherKeyPair(
                new ECPublicKeyParameters(
                    p.Curve.DecodePoint(Hex.Decode("02015198E74BC2F1E5C9A62B80248DF0D62B9ADF8429")), p),
                new ECPrivateKeyParameters(
                    new BigInteger("032FC4C61A8211E6A7C4B8B0C03CF35F7CF20DBD52", 16), p));

            IAsymmetricCipherKeyPair v1 = new AsymmetricCipherKeyPair(
                new ECPublicKeyParameters(
                    p.Curve.DecodePoint(Hex.Decode("03072783FAAB9549002B4F13140B88132D1C75B3886C")), p),
                new ECPrivateKeyParameters(
                    new BigInteger("57E8A78E842BF4ACD5C315AA0569DB1703541D96", 16), p));

            IAsymmetricCipherKeyPair v2 = new AsymmetricCipherKeyPair(
                new ECPublicKeyParameters(
                    p.Curve.DecodePoint(Hex.Decode("03067E3AEA3510D69E8EDD19CB2A703DDC6CF5E56E32")), p),
                new ECPrivateKeyParameters(
                    new BigInteger("02BD198B83A667A8D908EA1E6F90FD5C6D695DE94F", 16), p));

            IBigInteger x = CalculateAgreement(u1, u2, v1, v2);

            if (x == null ||
                !x.Equals(new BigInteger("038359FFD30C0D5FC1E6154F483B73D43E5CF2B503", 16)))
            {
                Fail("MQV Test Vector #2 agreement failed");
            }
        }
Beispiel #26
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));
        }
Beispiel #27
0
        private void doTestGPWithRandom(
            DHKeyPairGenerator kpGen)
        {
            //
            // generate first pair
            //
            IAsymmetricCipherKeyPair pair = kpGen.GenerateKeyPair();

            DHPublicKeyParameters  pu1 = (DHPublicKeyParameters)pair.Public;
            DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters)pair.Private;

            //
            // generate second pair
            //
            pair = kpGen.GenerateKeyPair();

            DHPublicKeyParameters  pu2 = (DHPublicKeyParameters)pair.Public;
            DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters)pair.Private;

            //
            // two way
            //
            DHAgreement e1 = new DHAgreement();
            DHAgreement e2 = new DHAgreement();

            e1.Init(new ParametersWithRandom(pv1, new SecureRandom()));
            e2.Init(new ParametersWithRandom(pv2, new SecureRandom()));

            IBigInteger m1 = e1.CalculateMessage();
            IBigInteger m2 = e2.CalculateMessage();

            IBigInteger k1 = e1.CalculateAgreement(pu2, m2);
            IBigInteger k2 = e2.CalculateAgreement(pu1, m1);

            if (!k1.Equals(k2))
            {
                Fail("basic with random 2-way test failed");
            }
        }
Beispiel #28
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        m          = new BigInteger(1, mRev);
            Gost3410Parameters parameters = key.Parameters;

            if (r.SignValue < 0 || parameters.Q.CompareTo(r) <= 0)
            {
                return(false);
            }

            if (s.SignValue < 0 || parameters.Q.CompareTo(s) <= 0)
            {
                return(false);
            }

            IBigInteger v = m.ModPow(parameters.Q.Subtract(BigInteger.Two), parameters.Q);

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

            z1 = parameters.A.ModPow(z1, parameters.P);
            z2 = ((Gost3410PublicKeyParameters)key).Y.ModPow(z2, parameters.P);

            IBigInteger u = z1.Multiply(z2).Mod(parameters.P).Mod(parameters.Q);

            return(u.Equals(r));
        }
Beispiel #29
0
 protected bool Equals(FPFieldElement other)
 {
     return(_q.Equals(other._q) && base.Equals(other));
 }
Beispiel #30
0
        public void TestECMqv()
        {
            IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("ECMQV");

//			EllipticCurve curve = new EllipticCurve(
//				new ECFieldFp(new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839")), // q
//				new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a
//				new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b
            ECCurve curve = new FPCurve(
                new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),         // q
                new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16),                 // a
                new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16));                // b

            ECDomainParameters ecSpec = new ECDomainParameters(
                curve,
//				ECPointUtil.DecodePoint(curve, Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
                curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
                new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"),      // n
                BigInteger.One);                                                                                 //1); // h

//			g.initialize(ecSpec, new SecureRandom());
            g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom()));

            //
            // U side
            //
            IAsymmetricCipherKeyPair U1 = g.GenerateKeyPair();
            IAsymmetricCipherKeyPair U2 = g.GenerateKeyPair();

            IBasicAgreement uAgree = AgreementUtilities.GetBasicAgreement("ECMQV");

            uAgree.Init(new MqvPrivateParameters(
                            (ECPrivateKeyParameters)U1.Private,
                            (ECPrivateKeyParameters)U2.Private,
                            (ECPublicKeyParameters)U2.Public));

            //
            // V side
            //
            IAsymmetricCipherKeyPair V1 = g.GenerateKeyPair();
            IAsymmetricCipherKeyPair V2 = g.GenerateKeyPair();

            IBasicAgreement vAgree = AgreementUtilities.GetBasicAgreement("ECMQV");

            vAgree.Init(new MqvPrivateParameters(
                            (ECPrivateKeyParameters)V1.Private,
                            (ECPrivateKeyParameters)V2.Private,
                            (ECPublicKeyParameters)V2.Public));

            //
            // agreement
            //
            IBigInteger ux = uAgree.CalculateAgreement(new MqvPublicParameters(
                                                           (ECPublicKeyParameters)V1.Public,
                                                           (ECPublicKeyParameters)V2.Public));
            IBigInteger vx = vAgree.CalculateAgreement(new MqvPublicParameters(
                                                           (ECPublicKeyParameters)U1.Public,
                                                           (ECPublicKeyParameters)U2.Public));

            if (!ux.Equals(vx))
            {
                Fail("Agreement failed");
            }
        }
Beispiel #31
0
 protected bool Equals(
     ElGamalParameters other)
 {
     return(p.Equals(other.p) && g.Equals(other.g) && l == other.l);
 }
Beispiel #32
0
        private void doTestGP(
            string algName,
            int size,
            int privateValueSize,
            IBigInteger g,
            IBigInteger p)
        {
            IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator(algName);

            DHParameters            dhParams = new DHParameters(p, g, null, privateValueSize);
            KeyGenerationParameters kgp      = new DHKeyGenerationParameters(new SecureRandom(), dhParams);

            keyGen.Init(kgp);

            //
            // a side
            //
            IAsymmetricCipherKeyPair aKeyPair = keyGen.GenerateKeyPair();

            IBasicAgreement aKeyAgreeBasic = AgreementUtilities.GetBasicAgreement(algName);

            checkKeySize(privateValueSize, aKeyPair);

            aKeyAgreeBasic.Init(aKeyPair.Private);

            //
            // b side
            //
            IAsymmetricCipherKeyPair bKeyPair = keyGen.GenerateKeyPair();

            IBasicAgreement bKeyAgreeBasic = AgreementUtilities.GetBasicAgreement(algName);

            checkKeySize(privateValueSize, bKeyPair);

            bKeyAgreeBasic.Init(bKeyPair.Private);

            //
            // agreement
            //
//			aKeyAgreeBasic.doPhase(bKeyPair.Public, true);
//			bKeyAgreeBasic.doPhase(aKeyPair.Public, true);
//
//			IBigInteger  k1 = new BigInteger(aKeyAgreeBasic.generateSecret());
//			IBigInteger  k2 = new BigInteger(bKeyAgreeBasic.generateSecret());
            IBigInteger k1 = aKeyAgreeBasic.CalculateAgreement(bKeyPair.Public);
            IBigInteger k2 = bKeyAgreeBasic.CalculateAgreement(aKeyPair.Public);

            if (!k1.Equals(k2))
            {
                Fail(size + " bit 2-way test failed");
            }

            //
            // public key encoding test
            //
//			byte[]              pubEnc = aKeyPair.Public.GetEncoded();
            byte[] pubEnc = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(aKeyPair.Public).GetDerEncoded();

//			KeyFactory          keyFac = KeyFactory.getInstance(algName);
//			X509EncodedKeySpec  pubX509 = new X509EncodedKeySpec(pubEnc);
//			DHPublicKey         pubKey = (DHPublicKey)keyFac.generatePublic(pubX509);
            DHPublicKeyParameters pubKey = (DHPublicKeyParameters)PublicKeyFactory.CreateKey(pubEnc);
//			DHParameterSpec     spec = pubKey.Parameters;
            DHParameters spec = pubKey.Parameters;

            if (!spec.G.Equals(dhParams.G) || !spec.P.Equals(dhParams.P))
            {
                Fail(size + " bit public key encoding/decoding test failed on parameters");
            }

            if (!((DHPublicKeyParameters)aKeyPair.Public).Y.Equals(pubKey.Y))
            {
                Fail(size + " bit public key encoding/decoding test failed on y value");
            }

            //
            // public key serialisation test
            //
            // TODO Put back in
//			MemoryStream bOut = new MemoryStream();
//			ObjectOutputStream oOut = new ObjectOutputStream(bOut);
//
//			oOut.WriteObject(aKeyPair.Public);
//
//			MemoryStream bIn = new MemoryStream(bOut.ToArray(), false);
//			ObjectInputStream oIn = new ObjectInputStream(bIn);
//
//			pubKey = (DHPublicKeyParameters)oIn.ReadObject();
            spec = pubKey.Parameters;

            if (!spec.G.Equals(dhParams.G) || !spec.P.Equals(dhParams.P))
            {
                Fail(size + " bit public key serialisation test failed on parameters");
            }

            if (!((DHPublicKeyParameters)aKeyPair.Public).Y.Equals(pubKey.Y))
            {
                Fail(size + " bit public key serialisation test failed on y value");
            }

            //
            // private key encoding test
            //
//			byte[] privEnc = aKeyPair.Private.GetEncoded();
            byte[] privEnc = PrivateKeyInfoFactory.CreatePrivateKeyInfo(aKeyPair.Private).GetDerEncoded();
//			PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc);
//			DHPrivateKeyParameters privKey = (DHPrivateKey)keyFac.generatePrivate(privPKCS8);
            DHPrivateKeyParameters privKey = (DHPrivateKeyParameters)PrivateKeyFactory.CreateKey(privEnc);

            spec = privKey.Parameters;

            if (!spec.G.Equals(dhParams.G) || !spec.P.Equals(dhParams.P))
            {
                Fail(size + " bit private key encoding/decoding test failed on parameters");
            }

            if (!((DHPrivateKeyParameters)aKeyPair.Private).X.Equals(privKey.X))
            {
                Fail(size + " bit private key encoding/decoding test failed on y value");
            }

            //
            // private key serialisation test
            //
            // TODO Put back in
//			bOut = new MemoryStream();
//			oOut = new ObjectOutputStream(bOut);
//
//			oOut.WriteObject(aKeyPair.Private);
//
//			bIn = new MemoryStream(bOut.ToArray(), false);
//			oIn = new ObjectInputStream(bIn);
//
//			privKey = (DHPrivateKeyParameters)oIn.ReadObject();
            spec = privKey.Parameters;

            if (!spec.G.Equals(dhParams.G) || !spec.P.Equals(dhParams.P))
            {
                Fail(size + " bit private key serialisation test failed on parameters");
            }

            if (!((DHPrivateKeyParameters)aKeyPair.Private).X.Equals(privKey.X))
            {
                Fail(size + " bit private key serialisation test failed on y value");
            }

            //
            // three party test
            //
            IAsymmetricCipherKeyPairGenerator aPairGen = GeneratorUtilities.GetKeyPairGenerator(algName);

            aPairGen.Init(new DHKeyGenerationParameters(new SecureRandom(), spec));
            IAsymmetricCipherKeyPair aPair = aPairGen.GenerateKeyPair();

            IAsymmetricCipherKeyPairGenerator bPairGen = GeneratorUtilities.GetKeyPairGenerator(algName);

            bPairGen.Init(new DHKeyGenerationParameters(new SecureRandom(), spec));
            IAsymmetricCipherKeyPair bPair = bPairGen.GenerateKeyPair();

            IAsymmetricCipherKeyPairGenerator cPairGen = GeneratorUtilities.GetKeyPairGenerator(algName);

            cPairGen.Init(new DHKeyGenerationParameters(new SecureRandom(), spec));
            IAsymmetricCipherKeyPair cPair = cPairGen.GenerateKeyPair();


            IBasicAgreement aKeyAgree = AgreementUtilities.GetBasicAgreement(algName);

            aKeyAgree.Init(aPair.Private);

            IBasicAgreement bKeyAgree = AgreementUtilities.GetBasicAgreement(algName);

            bKeyAgree.Init(bPair.Private);

            IBasicAgreement cKeyAgree = AgreementUtilities.GetBasicAgreement(algName);

            cKeyAgree.Init(cPair.Private);

//			Key ac = aKeyAgree.doPhase(cPair.Public, false);
//			Key ba = bKeyAgree.doPhase(aPair.Public, false);
//			Key cb = cKeyAgree.doPhase(bPair.Public, false);
//
//			aKeyAgree.doPhase(cb, true);
//			bKeyAgree.doPhase(ac, true);
//			cKeyAgree.doPhase(ba, true);
//
//			IBigInteger aShared = new BigInteger(aKeyAgree.generateSecret());
//			IBigInteger bShared = new BigInteger(bKeyAgree.generateSecret());
//			IBigInteger cShared = new BigInteger(cKeyAgree.generateSecret());

            DHPublicKeyParameters ac = new DHPublicKeyParameters(aKeyAgree.CalculateAgreement(cPair.Public), spec);
            DHPublicKeyParameters ba = new DHPublicKeyParameters(bKeyAgree.CalculateAgreement(aPair.Public), spec);
            DHPublicKeyParameters cb = new DHPublicKeyParameters(cKeyAgree.CalculateAgreement(bPair.Public), spec);

            IBigInteger aShared = aKeyAgree.CalculateAgreement(cb);
            IBigInteger bShared = bKeyAgree.CalculateAgreement(ac);
            IBigInteger cShared = cKeyAgree.CalculateAgreement(ba);

            if (!aShared.Equals(bShared))
            {
                Fail(size + " bit 3-way test failed (a and b differ)");
            }

            if (!cShared.Equals(bShared))
            {
                Fail(size + " bit 3-way test failed (c and b differ)");
            }
        }
        private void checkSignature(
			int						size,
			ECPrivateKeyParameters	sKey,
			ECPublicKeyParameters	vKey,
			ISigner					sgr,
			SecureRandom			k,
			byte[]					message,
			IBigInteger				r,
			IBigInteger				s)
        {
            sgr.Init(true, new ParametersWithRandom(sKey, k));

            sgr.BlockUpdate(message, 0, message.Length);

            byte[] sigBytes = sgr.GenerateSignature();

            sgr.Init(false, vKey);

            sgr.BlockUpdate(message, 0, message.Length);

            if (!sgr.VerifySignature(sigBytes))
            {
                Fail(size + " bit EC verification failed");
            }

            IBigInteger[] sig = derDecode(sigBytes);

            if (!r.Equals(sig[0]))
            {
                Fail(size + "bit"
                    + ": r component wrong." + SimpleTest.NewLine
                    + " expecting: " + r + SimpleTest.NewLine
                    + " got      : " + sig[0]);
            }

            if (!s.Equals(sig[1]))
            {
                Fail(size + "bit"
                    + ": s component wrong." + SimpleTest.NewLine
                    + " expecting: " + s + SimpleTest.NewLine
                    + " got      : " + sig[1]);
            }
        }
        public virtual X509CrlEntry GetRevokedCertificate(
			IBigInteger serialNumber)
        {
            IEnumerable certs = c.GetRevokedCertificateEnumeration();

            X509Name previousCertificateIssuer = IssuerDN;
            foreach (CrlEntry entry in certs)
            {
                X509CrlEntry crlEntry = new X509CrlEntry(entry, isIndirect, previousCertificateIssuer);

                if (serialNumber.Equals(entry.UserCertificate.Value))
                {
                    return crlEntry;
                }

                previousCertificateIssuer = crlEntry.GetCertificateIssuer();
            }

            return null;
        }
        public IBigInteger ModPow(
            IBigInteger exponent,
            IBigInteger m)
        {
            if (m.SignValue < 1)
                throw new ArithmeticException("Modulus must be positive");

            if (m.Equals(One))
                return Zero;

            if (exponent.SignValue == 0)
                return One;

            if (SignValue == 0)
                return Zero;

            int[] zVal = null;
            int[] yAccum = null;
            int[] yVal;

            // Montgomery exponentiation is only possible if the modulus is odd,
            // but AFAIK, this is always the case for crypto algo's
            bool useMonty = ((m.Magnitude[m.Magnitude.Length - 1] & 1) == 1);
            long mQ = 0;
            if (useMonty)
            {
                mQ = m.GetMQuote();

                // tmp = this * R mod m
                IBigInteger tmp = ShiftLeft(32*m.Magnitude.Length).Mod(m);
                zVal = tmp.Magnitude;

                useMonty = (zVal.Length <= m.Magnitude.Length);

                if (useMonty)
                {
                    yAccum = new int[m.Magnitude.Length + 1];
                    if (zVal.Length < m.Magnitude.Length)
                    {
                        var longZ = new int[m.Magnitude.Length];
                        zVal.CopyTo(longZ, longZ.Length - zVal.Length);
                        zVal = longZ;
                    }
                }
            }

            if (!useMonty)
            {
                if (Magnitude.Length <= m.Magnitude.Length)
                {
                    //zAccum = new int[m.Magnitude.Length * 2];
                    zVal = new int[m.Magnitude.Length];
                    Magnitude.CopyTo(zVal, zVal.Length - Magnitude.Length);
                }
                else
                {
                    //
                    // in normal practice we'll never see this...
                    //
                    IBigInteger tmp = Remainder(m);

                    //zAccum = new int[m.Magnitude.Length * 2];
                    zVal = new int[m.Magnitude.Length];
                    tmp.Magnitude.CopyTo(zVal, zVal.Length - tmp.Magnitude.Length);
                }

                yAccum = new int[m.Magnitude.Length*2];
            }

            yVal = new int[m.Magnitude.Length];

            //
            // from LSW to MSW
            //
            for (int i = 0; i < exponent.Magnitude.Length; i++)
            {
                int v = exponent.Magnitude[i];
                int bits = 0;

                if (i == 0)
                {
                    while (v > 0)
                    {
                        v <<= 1;
                        bits++;
                    }

                    //
                    // first time in initialise y
                    //
                    zVal.CopyTo(yVal, 0);

                    v <<= 1;
                    bits++;
                }

                while (v != 0)
                {
                    if (useMonty)
                    {
                        // Montgomery square algo doesn't exist, and a normal
                        // square followed by a Montgomery reduction proved to
                        // be almost as heavy as a Montgomery mulitply.
                        MultiplyMonty(yAccum, yVal, yVal, m.Magnitude, mQ);
                    }
                    else
                    {
                        Square(yAccum, yVal);
                        Remainder(yAccum, m.Magnitude);
                        Array.Copy(yAccum, yAccum.Length - yVal.Length, yVal, 0, yVal.Length);
                        ZeroOut(yAccum);
                    }
                    bits++;

                    if (v < 0)
                    {
                        if (useMonty)
                        {
                            MultiplyMonty(yAccum, yVal, zVal, m.Magnitude, mQ);
                        }
                        else
                        {
                            Multiply(yAccum, yVal, zVal);
                            Remainder(yAccum, m.Magnitude);
                            Array.Copy(yAccum, yAccum.Length - yVal.Length, yVal, 0,
                                       yVal.Length);
                            ZeroOut(yAccum);
                        }
                    }

                    v <<= 1;
                }

                while (bits < 32)
                {
                    if (useMonty)
                    {
                        MultiplyMonty(yAccum, yVal, yVal, m.Magnitude, mQ);
                    }
                    else
                    {
                        Square(yAccum, yVal);
                        Remainder(yAccum, m.Magnitude);
                        Array.Copy(yAccum, yAccum.Length - yVal.Length, yVal, 0, yVal.Length);
                        ZeroOut(yAccum);
                    }
                    bits++;
                }
            }

            if (useMonty)
            {
                // Return y * R^(-1) mod m by doing y * 1 * R^(-1) mod m
                ZeroOut(zVal);
                zVal[zVal.Length - 1] = 1;
                MultiplyMonty(yAccum, yVal, zVal, m.Magnitude, mQ);
            }

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

            return exponent.SignValue > 0
                       ? result
                       : result.ModInverse(m);
        }