コード例 #1
0
            /// <summary>
            ///     Осуществляет разделение ключа на несколько частей
            /// </summary>
            /// <param name="Key">Ключ, который необходимо разделить</param>
            /// <param name="CountOfFragments">Число фрагментов, на которые необходимо разделить ключ</param>
            /// <param name="module">Модуль, который будет определен исходя из ключа</param>
            /// <param name="Limit">Порог количества фрагментов, начиная с которого можно будет восстановить ключ</param>
            /// <returns>Массив наборов (x,y). x можно публиковать. y должен находиться в секрете.</returns>
            public static KeyValuePair <int, BigInteger>[] Share(BigInteger Key, int CountOfFragments,
                                                                 out BigInteger module,
                                                                 int Limit = -1)
            {
                if (Limit == -1)
                {
                    Limit = CountOfFragments;
                }
                module = GetBiggerRandomPrime(Key);

                //Вычислили модуль многочлена и знаем порог - пора генерировать многочлен.
                int[] coefs = new int[Limit];
                for (int i = 0; i < coefs.Length - 1; i++)
                {
                    coefs[i] = (int)RD.UniformDistribution(1, module - 1, 1)[0];
                }
                coefs[coefs.Length - 1] = (int)Key;
                Polynoms.ModularPolynom          sharepolynom = new Polynoms.ModularPolynom(coefs, (int)module);
                KeyValuePair <int, BigInteger>[] Keys         = new KeyValuePair <int, BigInteger> [CountOfFragments];
                for (int i = 1; i <= CountOfFragments; i++)
                {
                    Keys[i - 1] = new KeyValuePair <int, BigInteger>(i, (BigInteger)sharepolynom.GetValue(i));
                }
                return(Keys);
            }
コード例 #2
0
            /// <summary>
            ///     Тест Соловея-Штрассена. Имеет числа КарлМайкла
            /// </summary>
            /// <param name="source">Число, которое необходмио протестировать</param>
            /// <param name="count">Число прогонов теста</param>
            /// <returns></returns>
            public static PrimalityTestResult SSPT(BigInteger source, BigInteger count)
            {
                if (count >= source)
                {
                    throw new InvalidOperationException("Число прогонов теста не должно быть меньше тестируемого числа.");
                }
                if (source == 0)
                {
                    return(PrimalityTestResult.Composite);
                }
                if (source == 1)
                {
                    return(PrimalityTestResult.Unknown);
                }

                if (source < 0 || count <= 0)
                {
                    throw new InvalidOperationException(
                              "Тестируемое число и число его прогонов должны быть положительными числами!");
                }

                //нам необходимо, чтобы число было нечетным, поэтому мы отсеиваем все четные числа.
                if (source % 2 == 0)
                {
                    return(PrimalityTestResult.Composite);
                }
                BigInteger[] RestVariants = RD.UniformDistribution(2, source - 1, count);
                //отрезок [2,n-1]
                for (int i = 0; i < count; i++)
                {
                    BigInteger CurrentValue = RestVariants[i];
                    if (AdvancedEuclidsalgorithm.GCDResult(CurrentValue, source) != 1)
                    {
                        return(PrimalityTestResult.Composite);
                    }
                    //значение символа якоби
                    BigInteger jacobi = JacobiSymbol.Get(CurrentValue, source);
                    Comparison.LinearComparison comparison = new Comparison.LinearComparison(CurrentValue, source);
                    if (Comparison.MultiplicativeInverse.BinaryPowLinearComparison(comparison, (source - 1) / 2).LeastModulo != jacobi)
                    {
                        return(PrimalityTestResult.Composite);
                    }
                }

                return(PrimalityTestResult.Unknown);
            }
コード例 #3
0
            /// <summary>
            ///     Fermat Primality Test - тест на основе теоремы Ферма. Имеет псевдопростые числа
            /// </summary>
            /// <param name="source">Число, которое необходимо проверить на простотоу</param>
            /// ///
            /// <param name="count">Число прогонов теста. Чем больше, тем точнее ответ.</param>
            /// <returns></returns>
            /// <exception cref="InvalidOperationException"></exception>
            public static PrimalityTestResult FPT(int source, int count)
            {
                if (count >= source)
                {
                    throw new InvalidOperationException("Число прогонов теста должно быть меньше тестируемого числа.");
                }
                switch (source)
                {
                case 0:
                    return(PrimalityTestResult.Composite);

                case 1:
                    throw new InvalidOperationException("Единица не является ни простым, ни составным числом.");
                }

                if (source < 0 || count <= 0)
                {
                    throw new InvalidOperationException(
                              "Тестируемое число и количество прогонов должны быть положительными числами!");
                }

                BigInteger[] RestVariants = RD.UniformDistribution(2, source - 1, count);
                //отрезок [2,n-1]
                for (int i = 1; i <= count; i++)
                {
                    BigInteger CurrentValue = RestVariants[i - 1];
                    if (AdvancedEuclidsalgorithm.GCDResult(CurrentValue, source) != 1)
                    {
                        return(PrimalityTestResult.Composite);
                    }
                    Comparison.LinearComparison comparison = new Comparison.LinearComparison(CurrentValue, source);
                    if (Comparison.MultiplicativeInverse.BinaryPowLinearComparison(comparison, source - 1).A != 1)
                    {
                        return(PrimalityTestResult.Composite);
                    }
                }

                return(PrimalityTestResult.Unknown);
            }
コード例 #4
0
            /// <summary>
            ///     Тест Рабина Миллера. Имеет сильно псевдопростые числа
            /// </summary>
            /// <param name="source"></param>
            /// <param name="count"></param>
            /// <returns></returns>
            public static PrimalityTestResult MRPT(int source, int count)
            {
                if (count >= source)
                {
                    throw new InvalidOperationException("Число прогонов теста не должно быть меньше тестируемого числа.");
                }
                switch (source)
                {
                case 0:
                    return(PrimalityTestResult.Composite);

                case 1:
                    throw new InvalidOperationException("Единица не является ни простым, ни составным числом.");
                }

                if (source < 0 || count <= 0)
                {
                    throw new InvalidOperationException(
                              "Тестируемое число и число его прогонов должны быть положительными числами!");
                }

                //нам необходимо, чтобы число было нечетным, поэтому мы отсеиваем все четные числа.
                if (source % 2 == 0)
                {
                    return(PrimalityTestResult.Composite);
                }
                int t = source - 1;
                int s = 0;

                while (t % 2 == 0)
                {
                    t /= 2;
                    s++;
                }
                //n-1 = (2^s) * t


                BigInteger[] RestVariants = RD.UniformDistribution(2, source - 1, count);
                //отрезок [2,n-1]
                for (int i = 0; i < count; i++)
                {
                    BigInteger CurrentValue = RestVariants[i];
                    if (AdvancedEuclidsalgorithm.GCDResult(CurrentValue, source) != 1)
                    {
                        return(PrimalityTestResult.Composite);
                    }
                    //значение символа якоби
                    Comparison.LinearComparison comparison = new Comparison.LinearComparison(CurrentValue, source);
                    if (BigInteger.Abs((comparison = Comparison.MultiplicativeInverse.BinaryPowLinearComparison(comparison, t))
                                       .LeastModulo) == 1)
                    {
                        continue;
                    }

                    while (s != 1)
                    {
                        comparison = Comparison.MultiplicativeInverse.BinaryPowLinearComparison(comparison, 2);
                        if (comparison.LeastModulo == -1)
                        {
                            break;
                        }
                        if (--s == 0)
                        {
                            return(PrimalityTestResult.Composite);
                        }
                    }
                }

                return(PrimalityTestResult.Unknown);
            }