Example #1
0
        /// <summary>
        /// Calculates a public exponent on the basis of
        /// a pair of primes which form the RSA secret key and
        /// the number chosen as public exponent.
        /// </summary>
        /// <typeparam name="B">An implementation of <c>IBase</c> interface which specifies the digit base of <c>LongInt&lt;<typeparamref name="B"/>&gt;</c> numbers.</typeparam>
        /// <param name="secretKey">A pair of primes which form the RSA secret key.</param>
        /// <returns>The secret exponent of the RSA algorithm.</returns>
        public static LongInt <B> GetSecretExponent <B>(Point <LongInt <B> > secretKey, LongInt <B> publicExponent)
            where B : IBase, new()
        {
            Contract.Requires <ArgumentNullException>(publicExponent != null, "publicExponent");
            Contract.Requires <ArgumentNullException>(secretKey.X != null, "secretKey.X");
            Contract.Requires <ArgumentNullException>(secretKey.Y != null, "secretKey.Y");

            LongInt <B> totient = LongInt <B> .Helper.MultiplyFFTComplex(secretKey.X - 1, secretKey.Y - 1);

            return
                (WhiteMath <LongInt <B>, CalcLongInt <B> > .MultiplicativeInverse(publicExponent, totient));
        }
Example #2
0
            /// <summary>
            /// Returns the first half of the [rootDegree]th roots of unity series in the BigInteger field.
            /// Used in the recursive FFT algorithm in LongInt.Helper class.
            ///
            /// Root degree should be an exact power of two.
            /// </summary>
            /// <param name="rootDegree"></param>
            /// <returns></returns>
            public static BigInteger[] rootsOfUnityHalfGalois(int rootDegree, bool inverted)
            {
                Contract.Requires <ArgumentOutOfRangeException>(rootDegree > 0, "The degree of the root should be a positive power of two.");
                Contract.Ensures(
                    Contract.ForAll(
                        Contract.Result <BigInteger[]>(),
                        (x => WhiteMath <BigInteger, CalcBigInteger> .PowerIntegerModular(x, (ulong)rootDegree, NTT_MODULUS) == 1)));

                BigInteger[] result = new BigInteger[rootDegree / 2];

                // The first root of unity is obviously one.
                // -
                result[0] = 1;

                // Now we will learn what k it is in rootDegree == 2^k
                // -
                int rootDegreeCopy     = rootDegree;
                int rootDegreeExponent = 0;

                while (rootDegreeCopy > 1)
                {
                    rootDegreeCopy /= 2;
                    ++rootDegreeExponent;
                }

                // Now we obtain the principal 2^rootDegreeExponent-th root of unity.
                // -
                BigInteger principalRoot = WhiteMath <BigInteger, CalcBigInteger> .PowerIntegerModular(
                    NTT_MAX_ROOT_OF_UNITY_2_30,
                    WhiteMath <ulong, CalcULong> .PowerInteger(2, NTT_MAX_ROOT_OF_UNITY_DEGREE_EXPONENT - rootDegreeExponent),
                    NTT_MODULUS);

                // Calculate the desired roots of unity.
                // -
                for (int i = 1; i < rootDegree / 2; i++)
                {
                    // All the desired roots of unity are obtained as powers of the principal root.
                    // -
                    result[i] = result[i - 1] * principalRoot % NTT_MODULUS;
                }

                // If performing the inverse NTT, we should invert the roots.
                // -
                if (inverted)
                {
                    for (int i = 0; i < rootDegree / 2; ++i)
                    {
                        result[i] = WhiteMath <BigInteger, CalcBigInteger> .MultiplicativeInverse(result[i], NTT_MODULUS);
                    }
                }

                return(result);
            }
Example #3
0
            /// <summary>
            /// BACK FFT
            /// </summary>
            /// <param name="coefficients"></param>
            /// <returns></returns>
            internal static BigInteger[] Recursive_NTT_Inverse(IList <BigInteger> coefficients)
            {
                int n = coefficients.Count;

                BigInteger[] rootsHalf = rootsOfUnityHalfGalois(n, true);
                BigInteger[] result    = Recursive_NTT_Skeleton(coefficients, rootsHalf, 1, 0);

                // We should multiply the result by the multiplicative inverse of length.
                // -
                BigInteger lengthMultiplicativeInverse =
                    WhiteMath <BigInteger, CalcBigInteger> .MultiplicativeInverse(n, NTT_MODULUS);

                for (int i = 0; i < result.Length; i++)
                {
                    result[i] = (result[i] * lengthMultiplicativeInverse) % NTT_MODULUS;
                }

                return(result);
            }
Example #4
0
            /// <summary>
            /// BACK FFT
            /// </summary>
            /// <param name="coefficients"></param>
            /// <returns></returns>
            internal static BigInteger[] Recursive_NTT_Inverse(
                IList <BigInteger> coefficients,
                NTTFiniteFieldInfo finiteFieldInfo)
            {
                int n = coefficients.Count;

                BigInteger[] rootsHalf = rootsOfUnityHalfGalois(finiteFieldInfo, n, true);
                BigInteger[] result    = Recursive_NTT_Skeleton(coefficients, rootsHalf, finiteFieldInfo, 1, 0);

                // We should multiply the result by the multiplicative inverse of length
                // in contrast to the forward-NTT.
                // -
                BigInteger lengthMultiplicativeInverse =
                    WhiteMath <BigInteger, CalcBigInteger> .MultiplicativeInverse(n, finiteFieldInfo.primeModulus);

                for (int i = 0; i < result.Length; i++)
                {
                    result[i] = (result[i] * lengthMultiplicativeInverse) % finiteFieldInfo.primeModulus;
                }

                return(result);
            }
Example #5
0
            /// <summary>
            /// For debug purposes. Performs the NTT in a straightforward (quadratic) manner.
            /// </summary>
            internal static BigInteger[] __DB_Quadratic_NTT(IList <BigInteger> coefficients, bool back = false)
            {
                BigInteger[] rootsOfUnity = __DB__rootsOfUnityGalois(coefficients.Count, back);
                BigInteger[] result       = new BigInteger[coefficients.Count];

                for (int i = 0; i < rootsOfUnity.Length; ++i)
                {
                    BigInteger currentRoot = rootsOfUnity[i];

                    BigInteger hornerResult = 0;

                    for (int j = coefficients.Count - 1; j >= 0; --j)
                    {
                        hornerResult = (hornerResult * currentRoot + coefficients[j]) % NTT_MODULUS;
                    }

                    result[i] =
                        hornerResult *
                        (back ? WhiteMath <BigInteger, CalcBigInteger> .MultiplicativeInverse(coefficients.Count, NTT_MODULUS) : 1) % NTT_MODULUS;
                }

                return(result);
            }