Exemple #1
0
        /// <summary>
        /// This method returns the calculated amount of subbatches which is assumed to be the opimum.
        /// To determine all possible subbatches, the batchsize must be factorized into its primes.
        /// </summary>
        /// <param name="keyTranslator"></param>
        /// <returns></returns>
        public int GetAmountOfSubbatches(IKeyTranslator keyTranslator)
        {
            if (this.keyTranslator != keyTranslator)
            {
                //init code:
                this.keyTranslator = keyTranslator;

                //Find factors of OpenCL batch size:
                List <Msieve.Factor> factors = Msieve.TrivialFactorization(keyTranslator.GetOpenCLBatchSize());
                amountOfSubbatchesFactors = new List <int>();
                foreach (var fac in factors)
                {
                    for (int i = 0; i < fac.count; i++)
                    {
                        amountOfSubbatchesFactors.Add((int)fac.factor);
                    }
                }
                amountOfSubbatches = keyTranslator.GetOpenCLBatchSize();

                batchSizeFactors = new List <int>();
                DecreaseAmountOfSubbatches();

                lastDuration       = TimeSpan.MaxValue;
                optimisticDecrease = false;
                lastStepIncrease   = false;

                if (openCLMode == 1)    //normal load
                {
                    DecreaseAmountOfSubbatches();
                }
            }

            return(amountOfSubbatches);
        }
Exemple #2
0
        /// <summary>
        /// dynamically loads the msieve dll file and sets the callbacks
        /// </summary>
        private void initMsieveDLL()
        {
            msieveDLL = Msieve.GetMsieveDLL();
            msieve    = msieveDLL.GetType("Msieve.msieve");

            //init msieve with callbacks:
            MethodInfo initMsieve                = msieve.GetMethod("initMsieve");
            Object     callback_struct           = Activator.CreateInstance(msieveDLL.GetType("Msieve.callback_struct"));
            FieldInfo  prepareSievingField       = msieveDLL.GetType("Msieve.callback_struct").GetField("prepareSieving");
            FieldInfo  putTrivialFactorlistField = msieveDLL.GetType("Msieve.callback_struct").GetField("putTrivialFactorlist");
            Delegate   prepareSievingDel         = MulticastDelegate.CreateDelegate(msieveDLL.GetType("Msieve.prepareSievingDelegate"), this, "prepareSieving");
            Delegate   putTrivialFactorlistDel   = MulticastDelegate.CreateDelegate(msieveDLL.GetType("Msieve.putTrivialFactorlistDelegate"), this, "putTrivialFactorlist");

            prepareSievingField.SetValue(callback_struct, prepareSievingDel);
            putTrivialFactorlistField.SetValue(callback_struct, putTrivialFactorlistDel);
            initMsieve.Invoke(null, new object[1] {
                callback_struct
            });
        }
        public BigInteger[] Solve()
        {
            /* Solving a linear equation over a residue class is not so trivial if the modulus is not a prime.
             * This is because residue classes with a composite modulus is not a field, which means that not all elements
             * of this ring do have an inverse.
             * We cope with this problem by factorizing the modulus in its prime factors and solving gauss over them
             * separately (in the case of p^q (q>1) by using "hensel lifting").
             * We can use the chinese remainder theorem to get the solution we need then.
             * But what happens if we aren't able to factorize the modulus completely, because this is to inefficient?
             * There is a simple trick to cope with that:
             * Try the gauss algorithm with the composite modulus. Either you have luck and it works out without a problem
             * (in this case we can just go on), or the gauss algorithm will have a problem inverting some number.
             * In the last case, we can search for the gcd of this number and the composite modulus. This gcd is a factor of the modulus,
             * so that solving the equation helped us finding the factorization.
             */

            FiniteFieldGauss gauss  = new FiniteFieldGauss();
            HenselLifting    hensel = new HenselLifting();

            List <Msieve.Factor> modfactors = Msieve.TrivialFactorization(mod);
            List <KeyValuePair <BigInteger[], Msieve.Factor> > results;   //Stores the partial solutions together with their factors

            bool tryAgain;

            try
            {
                do
                {
                    results  = new List <KeyValuePair <BigInteger[], Msieve.Factor> >();
                    tryAgain = false;

                    for (int i = 0; i < modfactors.Count; i++)
                    {
                        if (modfactors[i].prime)    //mod prime
                        {
                            if (modfactors[i].count == 1)
                            {
                                results.Add(new KeyValuePair <BigInteger[], Msieve.Factor>(gauss.Solve(MatrixCopy(), modfactors[i].factor), modfactors[i]));
                            }
                            else
                            {
                                results.Add(new KeyValuePair <BigInteger[], Msieve.Factor>(hensel.Solve(MatrixCopy(), modfactors[i].factor, modfactors[i].count), modfactors[i]));
                            }
                        }
                        else    //mod composite
                        {
                            //Try using gauss:
                            try
                            {
                                BigInteger[] res = gauss.Solve(MatrixCopy(), modfactors[i].factor);
                                results.Add(new KeyValuePair <BigInteger[], Msieve.Factor>(res, modfactors[i]));   //Yeah, we had luck :)
                            }
                            catch (NotInvertibleException ex)
                            {
                                //We found a factor of modfactors[i]:
                                BigInteger           notInvertible = ex.NotInvertibleNumber;
                                List <Msieve.Factor> morefactors   = Msieve.TrivialFactorization(modfactors[i].factor / notInvertible);
                                List <Msieve.Factor> morefactors2  = Msieve.TrivialFactorization(notInvertible);
                                modfactors.RemoveAt(i);
                                ConcatFactorLists(modfactors, morefactors);
                                ConcatFactorLists(modfactors, morefactors2);
                                tryAgain = true;
                                break;
                            }
                        }
                    }
                } while (tryAgain);
            }
            catch (LinearDependentException ex)
            {
                //We have to throw away dependent rows and try again later:
                Array.Sort(ex.RowsToDelete, (a, b) => (b - a));
                foreach (int row in ex.RowsToDelete)
                {
                    matrix.RemoveAt(row);
                }
                return(null);
            }

            BigInteger[] result = new BigInteger[size];
            //"glue" the results together:
            for (int i = 0; i < size; i++)
            {
                List <KeyValuePair <BigInteger, BigInteger> > partSolItem = new List <KeyValuePair <BigInteger, BigInteger> >();
                for (int c = 0; c < results.Count; c++)
                {
                    partSolItem.Add(new KeyValuePair <BigInteger, BigInteger>(results[c].Key[i], BigInteger.Pow(results[c].Value.factor, results[c].Value.count)));
                }
                result[i] = CRT(partSolItem);
            }

            return(result);
        }