avt.DynamicFlashRotator.Net.RegCore.Cryptography.BigInteger.modInverse C# (CSharp) Method

modInverse() public method

public modInverse ( BigInteger modulus ) : BigInteger
modulus BigInteger
return BigInteger
        public BigInteger modInverse(BigInteger modulus)
        {
            BigInteger[] p = { 0, 1 };
            BigInteger[] q = new BigInteger[2];    // quotients
            BigInteger[] r = { 0, 0 };             // remainders

            int step = 0;

            BigInteger a = modulus;
            BigInteger b = this;

            while (b.dataLength > 1 || (b.dataLength == 1 && b.data[0] != 0)) {
                BigInteger quotient = new BigInteger();
                BigInteger remainder = new BigInteger();

                if (step > 1) {
                    BigInteger pval = (p[0] - (p[1] * q[0])) % modulus;
                    p[0] = p[1];
                    p[1] = pval;
                }

                if (b.dataLength == 1)
                    singleByteDivide(a, b, quotient, remainder);
                else
                    multiByteDivide(a, b, quotient, remainder);

                /*
                Console.WriteLine(quotient.dataLength);
                Console.WriteLine("{0} = {1}({2}) + {3}  p = {4}", a.ToString(10),
                                  b.ToString(10), quotient.ToString(10), remainder.ToString(10),
                                  p[1].ToString(10));
                */

                q[0] = q[1];
                r[0] = r[1];
                q[1] = quotient; r[1] = remainder;

                a = b;
                b = remainder;

                step++;
            }

            if (r[0].dataLength > 1 || (r[0].dataLength == 1 && r[0].data[0] != 1))
                throw (new ArithmeticException("No inverse!"));

            BigInteger result = ((p[0] - (p[1] * q[0])) % modulus);

            if ((result.data[maxLength - 1] & 0x80000000) != 0)
                result += modulus;  // get the least positive modulus

            return result;
        }

Usage Example

コード例 #1
0
ファイル: ezrsa.cs プロジェクト: dnnsharp/DynamicRotator
        // Generate an RSA keypair
        // Popular exponents are 3, 17 and 65537; the bigger it is, the slower encryption becomes
        public void GenerateKeyPair(int exponent)
        {
            for (; ; ) {
                BigInteger E = exponent;
                Random rand = new Random();
                int nbits = this.keylen * 8 / 2;                // so that P * Q < N

                // Find primes P and Q with Q < P so that:
                //      GCD (E, (P - 1) * (Q - 1)) == 1

                BigInteger P = null;
                BigInteger Q = null;
                BigInteger Pmin1 = null;
                BigInteger Qmin1 = null;
                BigInteger H = null;
                BigInteger GCD = null;

                do {
                    P = BigInteger.genPseudoPrime(nbits, 20, rand);
                    Q = BigInteger.genPseudoPrime(nbits, 20, rand);
                    if (P == Q)
                        continue;
                    if (P < Q) {
                        BigInteger swap = P;
                        P = Q;
                        Q = swap;
                    }

                    Pmin1 = P - 1;
                    Qmin1 = Q - 1;
                    H = Pmin1 * Qmin1;
                    GCD = H.gcd(E);
                }
                while (GCD != 1);

                // N = P * Q
                // D  = E^-1 mod ((P - 1) * (Q - 1))
                // DP = D mod (P - 1)
                // DQ = D mod (Q - 1)
                // QP = Q^-1 mod P

                this.N = P * Q;
                this.E = E;
                this.P = P;
                this.Q = Q;
                this.D = E.modInverse(H);
                this.DP = D.modPow(1, Pmin1);
                this.DQ = D.modPow(1, Qmin1);
                this.QP = Q.modInverse(P);

                // Check that this key actually works!
                // BigInteger.genPseudoPrime (rarely) returns a non-prime
                byte[] encrypt_me = new byte[this.keylen - 1];
                RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
                rng.GetBytes(encrypt_me);
                encrypt_me = pad_bytes(encrypt_me, this.keylen);       // ensure msg < modulus
                byte[] encrypted = DoPublic(encrypt_me);
                byte[] decrypted = DoPrivate(encrypted);
                if (compare_bytes(encrypt_me, 0, decrypted, 0, this.keylen))
                    return;
            }
        }