예제 #1
0
        /// <summary>
        /// This function generates a pair of public and private keys by following the
        /// steps to come up with values for p, q, N, r, E and D and combining them to
        /// make the respective keys.
        /// </summary>
        /// <param name="keySize">Bit size of keys to be generated </param>
        private void KeyGen(int keySize)
        {
            BigInteger p = msgOptions.Generate(keySize, 1);
            BigInteger q = msgOptions.Generate(1024 - keySize, 1);
            BigInteger N = BigInteger.Multiply(p, q);
            BigInteger r = BigInteger.Multiply(BigInteger.Subtract
                                                   (p, 1), BigInteger.Subtract(q, 1));
            BigInteger E = 65537;
            BigInteger D = PrimeCheckExtension.modInverse(E, r);

            var eBytes = E.ToByteArray();
            var nBytes = N.ToByteArray();
            var dBytes = D.ToByteArray();

            var eByteLength = eBytes.Length;
            var nByteLength = nBytes.Length;
            var dByteLength = dBytes.Length;
            var eByteSize   = BitConverter.GetBytes(eByteLength);
            var nByteSize   = BitConverter.GetBytes(nByteLength);
            var dByteSize   = BitConverter.GetBytes(dByteLength);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(eByteSize);
                Array.Reverse(nByteSize);
                Array.Reverse(dByteSize);
            }

            var publicKeyList  = new List <byte[]>();
            var privateKeyList = new List <byte[]>();

            publicKeyList.Add(eByteSize);
            publicKeyList.Add(eBytes);
            publicKeyList.Add(nByteSize);
            publicKeyList.Add(nBytes);

            privateKeyList.Add(dByteSize);
            privateKeyList.Add(dBytes);
            privateKeyList.Add(nByteSize);
            privateKeyList.Add(nBytes);

            var publicKeyArray  = publicKeyList.SelectMany(a => a).ToArray();
            var privateKeyArray = privateKeyList.SelectMany(a => a).ToArray();

            var privateKey = Convert.ToBase64String(privateKeyArray);
            var publicKey  = Convert.ToBase64String(publicKeyArray);


            //Write these Base64 encoded files to disk
            var pos         = Directory.GetCurrentDirectory().LastIndexOf("\\");
            var pvtPath     = Directory.GetCurrentDirectory().Substring(0, pos) + "\\private.key";
            var pubPath     = Directory.GetCurrentDirectory().Substring(0, pos) + "\\public.key";
            var pvtPathJson = Directory.GetCurrentDirectory().Substring(0, pos) + "\\private.txt";
            var pubPathJson = Directory.GetCurrentDirectory().Substring(0, pos) + "\\public.txt";
            //Console.WriteLine(pvtPath);

            KeyMessage pvtKeyObj = new KeyMessage();
            KeyMessage pubKeyObj = new KeyMessage();

            pvtKeyObj.email = new List <string>();
            pubKeyObj.email = new List <string>();
            pvtKeyObj.key   = privateKey;
            pubKeyObj.key   = publicKey;
            var pvtJsonObj = JObject.FromObject(pvtKeyObj);
            var pubJsonObj = JObject.FromObject(pubKeyObj);

            //Console.WriteLine("Generating public key...\n" + pubJsonObj.ToString());
            //Console.WriteLine("Generating private key ... \n" + pvtJsonObj.ToString());
            File.WriteAllText(pvtPath, privateKey);
            File.WriteAllText(pubPath, publicKey);
            File.WriteAllText(pvtPathJson, pvtJsonObj.ToString());
            File.WriteAllText(pubPathJson, pubJsonObj.ToString());
        }
예제 #2
0
        /// <summary>
        /// A parallel foreach loop instantiates a BigInteger using the RNGCryptoServiceProvider.
        /// This function also uses the isProbablyPrime() function from the PrimeCheckExtension class.
        /// Parallel options has been used to modify how the ForEach loop runs and doesnt crash due to running
        /// out of memory. For every BigInteger, it is checked for prime and once the number of primes found is
        /// equal to the required number (count), the process is terminated.
        /// </summary>
        /// <param name="bits">BitLength of the numbers to be checked</param>
        /// <param name="count">The number of prime numbers to be generated</param>
        public BigInteger Generate(int bits, int count)
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            ParallelOptions         po  = new ParallelOptions();

            // to avoid running out of memory
            po.MaxDegreeOfParallelism = 20;
            // to facilitate termination of all threads if the condition (required number of primes)
            // has been met
            po.CancellationToken = cts.Token;
            BigInteger primeNum = 0;
            //counter for number of primes found. Will be compared to [count] to check if requirement has been met
            var cnt = 0;

            RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();

            // to run maximum number of threads possible. The code crashes (runs out of memory)
            // in the case of
            List <int> thread_ids = Enumerable.Range(1, Int16.MaxValue).ToList();

            try
            {
                Parallel.ForEach(thread_ids, po, (id, state) =>
                {
                    //instantiation of BigInteger
                    var byteArray = new byte[(bits / 8)];
                    provider.GetBytes(byteArray);
                    BigInteger bigNum = new BigInteger(byteArray);

                    // if bigInteger generated is negative
                    if (bigNum < 0)
                    {
                        bigNum *= -1;
                    }

                    var isPrime = PrimeCheckExtension.IsProbablyPrime(bigNum);


                    //Making updation of counter and printing thread safe
                    lock (myLock)
                    {
                        if (isPrime)
                        {
                            primeNum = bigNum;
                            cnt      = cnt + 1;
                            //To terminate all OTHER threads if the required number of threads has been reached
                            cts.Token.ThrowIfCancellationRequested();

                            //Printing prime numbers as they are found
                            //Console.WriteLine("\n{0}: {1}", cnt, bigNum);



                            if (cnt == count)
                            {
                                cts.Cancel();
                            }
                        }
                    }
                });
            }
            catch (OperationCanceledException)
            {
                //Console.WriteLine("Wooho ");
                //return 0;
                return(primeNum);
            }
            return(primeNum);
        }