Esempio n. 1
0
        } //ModularMath.MultiplicativeInverse(long,long)

        /// <summary>
        /// Computes the multiplicative inverse of <paramref name="a"/> modulo <paramref name="modulus"/>.
        /// </summary>
        /// <param name="a">A non-negative integer less than <paramref name="modulus"/>.</param>
        /// <param name="modulus">A non-negative integer defining the integer ring in which <paramref name="a"/> resides.</param>
        /// <returns>The multiplicative inverse of <paramref name="a"/> modulo <paramref name="modulus"/>,
        /// or null if no such multiplicative inverse exists.</returns>
        public static MyUInt256 MultiplicativeInverse(MyUInt256 a, MyUInt256 modulus)
        {
            if (a.IsMsbSet() || a.Compare(modulus) >= 0)
            {
                throw new ArgumentOutOfRangeException("a must be a non-negative integer less than modulus");
            }

            if (a.IsZero())
            {
                return(null);
            }

            MyUInt256 mi;

            ExtendedEuclidean(a, modulus, out mi);

            return(mi);
        } //ModularMath.MultiplicativeInverse(MyUInt256,MyUInt256)
Esempio n. 2
0
        } //ModularMath.ExtendedEuclidean(long,long,out ulong)

        /// <summary>
        /// Computes the greatest common divisor (GCD) of <paramref name="a"/> and <paramref name="b"/>,
        /// as well as the multiplicative inverse of <paramref name="a"/> modulo <paramref name="b"/>.
        /// </summary>
        /// <param name="a">A positive integer less than <paramref name="b"/>.</param>
        /// <param name="b">A positive integer greater than <paramref name="a"/>.</param>
        /// <param name="mulInverse">Receives the multiplicative inverse of <paramref name="a"/> modulo <paramref name="b"/>
        /// if <paramref name="a"/> and <paramref name="b"/> are coprime, or null otherwise.</param>
        /// <returns>The greatest common divisor of <paramref name="a"/> and <paramref name="b"/>.</returns>
        public static MyUInt256 ExtendedEuclidean(MyUInt256 a, MyUInt256 b, out MyUInt256 mulInverse)
        {
            if (a.IsZero() || a.Compare(b) >= 0)
            {
                throw new ArgumentOutOfRangeException("a must be a positive integer less than b");
            }

            MyUInt256 r0 = new MyUInt256(b), r1 = new MyUInt256(a); // ordered this way because b > a
            MyUInt256 q = new MyUInt256(), r = new MyUInt256();
            MyUInt256 x0 = new MyUInt256(0), x1 = new MyUInt256(1); // x is a's coefficient; we don't maintain b's coefficient
            MyUInt256 x   = new MyUInt256(1);                       // return multiplicative inverse of 1 if loop breaks before x is assigned and if GCD (q) is 1
            MyUInt256 tmp = new MyUInt256();

            for (; ;)
            {
                r.Set(r0);  // r = r0 % r1
                r.Modulo(r1);
                if (r.IsZero())
                {
                    break;  // break before overwriting previous value of q
                }
                q.Set(r0);  // q = r0 / r1
                q.Divide(r1);

                x.Set(x0);  // x = x0 - q * x1
                tmp.Set(q);
                tmp.Multiply(x1);
                x.Subtract(tmp);

                r0.Set(r1); r1.Set(r);
                x0.Set(x1); x1.Set(x);
            }

            if (x.IsMsbSet())
            {
                x.Add(b);
            }
            mulInverse = (r1.Compare(1) == 0 ? x : null);

            return(r1);
        } //ModularMath.ExtendedEuclidean(MyUInt256,MyUInt256,out MyUInt256)
Esempio n. 3
0
        /// <summary>
        /// Computes the greatest common divisor (GCD) of <paramref name="a"/> and <paramref name="b"/>,
        /// as well as the multiplicative inverse of <paramref name="a"/> modulo <paramref name="b"/>.
        /// </summary>
        /// <param name="a">A positive integer less than <paramref name="b"/>.</param>
        /// <param name="b">A positive integer greater than <paramref name="a"/>.</param>
        /// <param name="mulInverse">Receives the multiplicative inverse of <paramref name="a"/> modulo <paramref name="b"/>
        /// if <paramref name="a"/> and <paramref name="b"/> are coprime, or null otherwise.</param>
        /// <returns>The greatest common divisor of <paramref name="a"/> and <paramref name="b"/>.</returns>
        public static MyUInt256 ExtendedEuclidean(MyUInt256 a, MyUInt256 b, out MyUInt256 mulInverse)
        {
            if (a.IsZero() || a.Compare(b) >= 0)
                throw new ArgumentOutOfRangeException("a must be a positive integer less than b");

            MyUInt256 r0 = new MyUInt256(b), r1 = new MyUInt256(a);  // ordered this way because b > a
            MyUInt256 q = new MyUInt256(), r = new MyUInt256();
            MyUInt256 x0 = new MyUInt256(0), x1 = new MyUInt256(1);  // x is a's coefficient; we don't maintain b's coefficient
            MyUInt256 x = new MyUInt256(1);  // return multiplicative inverse of 1 if loop breaks before x is assigned and if GCD (q) is 1
            MyUInt256 tmp = new MyUInt256();

            for (; ; )
            {
                r.Set(r0);  // r = r0 % r1
                r.Modulo(r1);
                if (r.IsZero()) break;  // break before overwriting previous value of q

                q.Set(r0);  // q = r0 / r1
                q.Divide(r1);

                x.Set(x0);  // x = x0 - q * x1
                tmp.Set(q);
                tmp.Multiply(x1);
                x.Subtract(tmp);

                r0.Set(r1); r1.Set(r);
                x0.Set(x1); x1.Set(x);
            }

            if (x.IsMsbSet()) x.Add(b);
            mulInverse = (r1.Compare(1) == 0 ? x : null);

            return r1;
        }
Esempio n. 4
0
        /// <summary>
        /// Computes the multiplicative inverse of <paramref name="a"/> modulo <paramref name="modulus"/>.
        /// </summary>
        /// <param name="a">A non-negative integer less than <paramref name="modulus"/>.</param>
        /// <param name="modulus">A non-negative integer defining the integer ring in which <paramref name="a"/> resides.</param>
        /// <returns>The multiplicative inverse of <paramref name="a"/> modulo <paramref name="modulus"/>,
        /// or null if no such multiplicative inverse exists.</returns>
        public static MyUInt256 MultiplicativeInverse(MyUInt256 a, MyUInt256 modulus)
        {
            if (a.IsMsbSet() || a.Compare(modulus) >= 0)
                throw new ArgumentOutOfRangeException("a must be a non-negative integer less than modulus");

            if (a.IsZero())
                return null;

            MyUInt256 mi;
            ExtendedEuclidean(a, modulus, out mi);

            return mi;
        }