Normalize() private method

Normalizes this by setting the length to the actual number of uints used in data and by setting the sign to Sign.Zero if the value of this is 0.
private Normalize ( ) : void
return void
Beispiel #1
0
            public static BigInteger RightShift(BigInteger bi, int n)
            {
                if (n == 0)
                {
                    return(new BigInteger(bi));
                }

                int w = n >> 5;
                int s = n & ((1 << 5) - 1);

                BigInteger ret = new BigInteger(Sign.Positive, bi.length - (uint)w + 1);
                uint       l   = (uint)ret.data.Length - 1;

                if (s != 0)
                {
                    uint x, carry = 0;

                    while (l-- > 0)
                    {
                        x           = bi.data[l + w];
                        ret.data[l] = (x >> n) | carry;
                        carry       = x << (32 - n);
                    }
                }
                else
                {
                    while (l-- > 0)
                    {
                        ret.data[l] = bi.data[l + w];
                    }
                }
                ret.Normalize();
                return(ret);
            }
Beispiel #2
0
        public static BigInteger operator *(BigInteger bi1, BigInteger bi2)
        {
            if (bi1 == 0 || bi2 == 0)
            {
                return(0);
            }

            //
            // Validate pointers
            //
            if (bi1.data.Length < bi1.length)
            {
                throw new IndexOutOfRangeException("bi1 out of range");
            }
            if (bi2.data.Length < bi2.length)
            {
                throw new IndexOutOfRangeException("bi2 out of range");
            }

            BigInteger ret = new BigInteger(Sign.Positive, bi1.length + bi2.length);

            Kernel.Multiply(bi1.data, 0, bi1.length, bi2.data, 0, bi2.length, ret.data, 0);

            ret.Normalize();
            return(ret);
        }
            public void BarrettReduction(BigInteger x)
            {
                var n = mod;
                uint k = n.length,
                    kPlusOne = k + 1,
                    kMinusOne = k - 1;

                // x < mod, so nothing to do.
                if (x.length < k) return;

                BigInteger q3;

                //
                // Validate pointers
                //
                if (x.data.Length < x.length) throw new IndexOutOfRangeException("x out of range");

                // q1 = x / b^ (k-1)
                // q2 = q1 * constant
                // q3 = q2 / b^ (k+1), Needs to be accessed with an offset of kPlusOne

                // TODO: We should the method in HAC p 604 to do this (14.45)
                q3 = new BigInteger(Sign.Positive, x.length - kMinusOne + constant.length);
                Kernel.Multiply(x.data, kMinusOne, x.length - kMinusOne, constant.data, 0, constant.length, q3.data, 0);

                // r1 = x mod b^ (k+1)
                // i.e. keep the lowest (k+1) words

                var lengthToCopy = x.length > kPlusOne ? kPlusOne : x.length;

                x.length = lengthToCopy;
                x.Normalize();

                // r2 = (q3 * n) mod b^ (k+1)
                // partial multiplication of q3 and n

                var r2 = new BigInteger(Sign.Positive, kPlusOne);
                Kernel.MultiplyMod2p32pmod(q3.data, (int) kPlusOne, (int) q3.length - (int) kPlusOne, n.data, 0,
                    (int) n.length, r2.data, 0, (int) kPlusOne);

                r2.Normalize();

                if (r2 <= x)
                {
                    Kernel.MinusEq(x, r2);
                }
                else
                {
                    var val = new BigInteger(Sign.Positive, kPlusOne + 1);
                    val.data[kPlusOne] = 0x00000001;

                    Kernel.MinusEq(val, r2);
                    Kernel.PlusEq(x, val);
                }

                while (x >= n)
                    Kernel.MinusEq(x, n);
            }
Beispiel #4
0
            public static BigInteger Subtract(BigInteger big, BigInteger small)
            {
                BigInteger result = new BigInteger(Sign.Positive, big.length);

                uint[] r = result.data, b = big.data, s = small.data;
                uint   i = 0, c = 0;

                do
                {
                    uint x = s[i];
                    if (((x += c) < c) | ((r[i] = b[i] - x) > ~x))
                    {
                        c = 1;
                    }
                    else
                    {
                        c = 0;
                    }
                } while (++i < small.length);

                if (i == big.length)
                {
                    goto fixup;
                }

                if (c == 1)
                {
                    do
                    {
                        r[i] = b[i] - 1;
                    }while (b[i++] == 0 && i < big.length);

                    if (i == big.length)
                    {
                        goto fixup;
                    }
                }

                do
                {
                    r[i] = b[i];
                }while (++i < big.length);

fixup:

                result.Normalize();
                return(result);
            }
Beispiel #5
0
            /// <summary>
            /// Performs n / d and n % d in one operation.
            /// </summary>
            /// <param name="n">A BigInteger, upon exit this will hold n / d</param>
            /// <param name="d">The divisor</param>
            /// <returns>n % d</returns>
            public static uint SingleByteDivideInPlace(BigInteger n, uint d)
            {
                ulong r = 0;
                uint  i = n.length;

                while (i-- > 0)
                {
                    r       <<= 32;
                    r        |= n.data[i];
                    n.data[i] = (uint)(r / d);
                    r        %= d;
                }
                n.Normalize();

                return((uint)r);
            }
Beispiel #6
0
            public static BigInteger MultiplyByDword(BigInteger n, uint f)
            {
                BigInteger ret = new BigInteger(Sign.Positive, n.length + 1);

                uint  i = 0;
                ulong c = 0;

                do
                {
                    c          += (ulong)n.data[i] * (ulong)f;
                    ret.data[i] = (uint)c;
                    c         >>= 32;
                } while (++i < n.length);
                ret.data[i] = (uint)c;
                ret.Normalize();
                return(ret);
            }
Beispiel #7
0
            public static BigInteger DwordDiv(BigInteger n, uint d)
            {
                BigInteger ret = new BigInteger(Sign.Positive, n.length);

                ulong r = 0;
                uint  i = n.length;

                while (i-- > 0)
                {
                    r         <<= 32;
                    r          |= n.data[i];
                    ret.data[i] = (uint)(r / d);
                    r          %= d;
                }
                ret.Normalize();

                return(ret);
            }
Beispiel #8
0
            public static BigInteger LeftShift(BigInteger bi, int n)
            {
                if (n == 0)
                {
                    return(new BigInteger(bi, bi.length + 1));
                }

                int w = n >> 5;

                n &= ((1 << 5) - 1);

                BigInteger ret = new BigInteger(Sign.Positive, bi.length + 1 + (uint)w);

                uint i = 0, l = bi.length;

                if (n != 0)
                {
                    uint x, carry = 0;
                    while (i < l)
                    {
                        x = bi.data[i];
                        ret.data[i + w] = (x << n) | carry;
                        carry           = x >> (32 - n);
                        i++;
                    }
                    ret.data[i + w] = carry;
                }
                else
                {
                    while (i < l)
                    {
                        ret.data[i + w] = bi.data[i];
                        i++;
                    }
                }

                ret.Normalize();
                return(ret);
            }
Beispiel #9
0
			public static void PlusEq (BigInteger bi1, BigInteger bi2)
			{
				uint [] x, y;
				uint yMax, xMax, i = 0;
				bool flag = false;

				// x should be bigger
				if (bi1.length < bi2.length){
					flag = true;
					x = bi2.data;
					xMax = bi2.length;
					y = bi1.data;
					yMax = bi1.length;
				} else {
					x = bi1.data;
					xMax = bi1.length;
					y = bi2.data;
					yMax = bi2.length;
				}

				uint [] r = bi1.data;

				ulong sum = 0;

				// Add common parts of both numbers
				do {
					sum += ((ulong)x [i]) + ((ulong)y [i]);
					r [i] = (uint)sum;
					sum >>= 32;
				} while (++i < yMax);

				// Copy remainder of longer number while carry propagation is required
				bool carry = (sum != 0);

				if (carry){

					if (i < xMax) {
						do
							carry = ((r [i] = x [i] + 1) == 0);
						while (++i < xMax && carry);
					}

					if (carry) {
						r [i] = 1;
						bi1.length = ++i;
						return;
					}
				}

				// Copy the rest
				if (flag && i < xMax - 1) {
					do
						r [i] = x [i];
					while (++i < xMax);
				}

				bi1.length = xMax + 1;
				bi1.Normalize ();
			}
Beispiel #10
0
			public static BigInteger Subtract (BigInteger big, BigInteger small)
			{
				BigInteger result = new BigInteger (Sign.Positive, big.length);

				uint [] r = result.data, b = big.data, s = small.data;
				uint i = 0, c = 0;

				do {

					uint x = s [i];
					if (((x += c) < c) | ((r [i] = b [i] - x) > ~x))
						c = 1;
					else
						c = 0;

				} while (++i < small.length);

				if (i == big.length) goto fixup;

				if (c == 1) {
					do
						r [i] = b [i] - 1;
					while (b [i++] == 0 && i < big.length);

					if (i == big.length) goto fixup;
				}

				do
					r [i] = b [i];
				while (++i < big.length);

				fixup:

					result.Normalize ();
				return result;
			}
Beispiel #11
0
			/// <summary>
			/// Adds two numbers with the same sign.
			/// </summary>
			/// <param name="bi1">A BigInteger</param>
			/// <param name="bi2">A BigInteger</param>
			/// <returns>bi1 + bi2</returns>
			public static BigInteger AddSameSign (BigInteger bi1, BigInteger bi2)
			{
				uint [] x, y;
				uint yMax, xMax, i = 0;

				// x should be bigger
				if (bi1.length < bi2.length) {
					x = bi2.data;
					xMax = bi2.length;
					y = bi1.data;
					yMax = bi1.length;
				} else {
					x = bi1.data;
					xMax = bi1.length;
					y = bi2.data;
					yMax = bi2.length;
				}
				
				BigInteger result = new BigInteger (Sign.Positive, xMax + 1);

				uint [] r = result.data;

				ulong sum = 0;

				// Add common parts of both numbers
				do {
					sum = ((ulong)x [i]) + ((ulong)y [i]) + sum;
					r [i] = (uint)sum;
					sum >>= 32;
				} while (++i < yMax);

				// Copy remainder of longer number while carry propagation is required
				bool carry = (sum != 0);

				if (carry) {

					if (i < xMax) {
						do
							carry = ((r [i] = x [i] + 1) == 0);
						while (++i < xMax && carry);
					}

					if (carry) {
						r [i] = 1;
						result.length = ++i;
						return result;
					}
				}

				// Copy the rest
				if (i < xMax) {
					do
						r [i] = x [i];
					while (++i < xMax);
				}

				result.Normalize ();
				return result;
			}
Beispiel #12
0
			public static BigInteger ToMont (BigInteger n, BigInteger m)
			{
				n.Normalize (); m.Normalize ();

				n <<= (int)m.length * 32;
				n %= m;
				return n;
			}
Beispiel #13
0
/* known to be buggy in some cases */
#if false
			private unsafe BigInteger EvenModTwoPow (BigInteger exp)
			{
				exp.Normalize ();
				uint [] wkspace = new uint [mod.length << 1 + 1];

				BigInteger resultNum = new BigInteger (2, mod.length << 1 +1);

				uint value = exp.data [exp.length - 1];
				uint mask = 0x80000000;

				// Find the first bit of the exponent
				while ((value & mask) == 0)
					mask >>= 1;

				//
				// We know that the first itr will make the val 2,
				// so eat one bit of the exponent
				//
				mask >>= 1;

				uint wPos = exp.length - 1;

				do {
					value = exp.data [wPos];
					do {
						Kernel.SquarePositive (resultNum, ref wkspace);
						if (resultNum.length >= mod.length)
							BarrettReduction (resultNum);

						if ((value & mask) != 0) {
							//
							// resultNum = (resultNum * 2) % mod
							//

							fixed (uint* u = resultNum.data) {
								//
								// Double
								//
								uint* uu = u;
								uint* uuE = u + resultNum.length;
								uint x, carry = 0;
								while (uu < uuE) {
									x = *uu;
									*uu = (x << 1) | carry;
									carry = x >> (32 - 1);
									uu++;
								}

								// subtraction inlined because we know it is square
								if (carry != 0 || resultNum >= mod) {
									uu = u;
									uint c = 0;
									uint [] s = mod.data;
									uint i = 0;
									do {
										uint a = s [i];
										if (((a += c) < c) | ((* (uu++) -= a) > ~a))
											c = 1;
										else
											c = 0;
										i++;
									} while (uu < uuE);
								}
							}
						}
					} while ((mask >>= 1) > 0);
					mask = 0x80000000;
				} while (wPos-- > 0);

				return resultNum;
			}
Beispiel #14
0
            public static BigInteger[] multiByteDivide(BigInteger bi1, BigInteger bi2)
            {
                if (Compare(bi1, bi2) == Sign.Negative)
                {
                    return new BigInteger[] { 0, new BigInteger(bi1) }
                }
                ;

                bi1.Normalize(); bi2.Normalize();

                if (bi2.length == 1)
                {
                    return(DwordDivMod(bi1, bi2.data[0]));
                }

                var remainderLen = bi1.length + 1;
                var divisorLen   = (int)bi2.length + 1;

                var mask      = 0x80000000;
                var val       = bi2.data[bi2.length - 1];
                var shift     = 0;
                var resultPos = (int)bi1.length - (int)bi2.length;

                while (mask != 0 && (val & mask) == 0)
                {
                    shift++; mask >>= 1;
                }

                var quot = new BigInteger(Sign.Positive, bi1.length - bi2.length + 1);
                var rem  = (bi1 << shift);

                var remainder = rem.data;

                bi2 = bi2 << shift;

                var j   = (int)(remainderLen - bi2.length);
                int pos = (int)remainderLen - 1;

                uint  firstDivisorByte  = bi2.data[bi2.length - 1];
                ulong secondDivisorByte = bi2.data[bi2.length - 2];

                while (j > 0)
                {
                    var dividend = ((ulong)remainder[pos] << 32) + remainder[pos - 1];

                    var qHat = dividend / firstDivisorByte;
                    var rHat = dividend % firstDivisorByte;

                    do
                    {
                        if (qHat == 0x100000000 ||
                            (qHat * secondDivisorByte) > ((rHat << 32) + remainder[pos - 2]))
                        {
                            qHat--;
                            rHat += firstDivisorByte;

                            if (rHat < 0x100000000)
                            {
                                continue;
                            }
                        }
                        break;
                    } while (true);

                    //
                    // At this point, q_hat is either exact, or one too large
                    // (more likely to be exact) so, we attempt to multiply the
                    // divisor by q_hat, if we get a borrow, we just subtract
                    // one from q_hat and add the divisor back.
                    //

                    uint  t;
                    uint  dPos       = 0;
                    int   nPos       = pos - divisorLen + 1;
                    ulong mc         = 0;
                    uint  uint_q_hat = (uint)qHat;
                    do
                    {
                        mc += (ulong)bi2.data[dPos] * uint_q_hat;
                        t   = remainder[nPos];
                        remainder[nPos] -= (uint)mc;
                        mc >>= 32;
                        if (remainder[nPos] > t)
                        {
                            mc++;
                        }
                        dPos++; nPos++;
                    } while (dPos < divisorLen);

                    nPos = pos - divisorLen + 1;
                    dPos = 0;

                    // Overestimate
                    if (mc != 0)
                    {
                        uint_q_hat--;
                        ulong sum = 0;

                        do
                        {
                            sum             = ((ulong)remainder[nPos]) + bi2.data[dPos] + sum;
                            remainder[nPos] = (uint)sum;
                            sum           >>= 32;
                            dPos++; nPos++;
                        } while (dPos < divisorLen);
                    }

                    quot.data[resultPos--] = uint_q_hat;

                    pos--;
                    j--;
                }

                quot.Normalize();
                rem.Normalize();
                var ret = new[] { quot, rem };

                if (shift != 0)
                {
                    ret[1] >>= shift;
                }

                return(ret);
            }
Beispiel #15
0
			public static BigInteger [] multiByteDivide (BigInteger bi1, BigInteger bi2)
			{
				if (Kernel.Compare (bi1, bi2) == Sign.Negative)
					return new BigInteger [2] { 0, new BigInteger (bi1) };

				bi1.Normalize (); bi2.Normalize ();

				if (bi2.length == 1)
					return DwordDivMod (bi1, bi2.data [0]);

				uint remainderLen = bi1.length + 1;
				int divisorLen = (int)bi2.length + 1;

				uint mask = 0x80000000;
				uint val = bi2.data [bi2.length - 1];
				int shift = 0;
				int resultPos = (int)bi1.length - (int)bi2.length;

				while (mask != 0 && (val & mask) == 0) {
					shift++; mask >>= 1;
				}

				BigInteger quot = new BigInteger (Sign.Positive, bi1.length - bi2.length + 1);
				BigInteger rem = (bi1 << shift);

				uint [] remainder = rem.data;

				bi2 = bi2 << shift;

				int j = (int)(remainderLen - bi2.length);
				int pos = (int)remainderLen - 1;

				uint firstDivisorByte = bi2.data [bi2.length-1];
				ulong secondDivisorByte = bi2.data [bi2.length-2];

				while (j > 0) {
					ulong dividend = ((ulong)remainder [pos] << 32) + (ulong)remainder [pos-1];

					ulong q_hat = dividend / (ulong)firstDivisorByte;
					ulong r_hat = dividend % (ulong)firstDivisorByte;

					do {

						if (q_hat == 0x100000000 ||
							(q_hat * secondDivisorByte) > ((r_hat << 32) + remainder [pos-2])) {
							q_hat--;
							r_hat += (ulong)firstDivisorByte;

							if (r_hat < 0x100000000)
								continue;
						}
						break;
					} while (true);

					//
					// At this point, q_hat is either exact, or one too large
					// (more likely to be exact) so, we attempt to multiply the
					// divisor by q_hat, if we get a borrow, we just subtract
					// one from q_hat and add the divisor back.
					//

					uint t;
					uint dPos = 0;
					int nPos = pos - divisorLen + 1;
					ulong mc = 0;
					uint uint_q_hat = (uint)q_hat;
					do {
						mc += (ulong)bi2.data [dPos] * (ulong)uint_q_hat;
						t = remainder [nPos];
						remainder [nPos] -= (uint)mc;
						mc >>= 32;
						if (remainder [nPos] > t) mc++;
						dPos++; nPos++;
					} while (dPos < divisorLen);

					nPos = pos - divisorLen + 1;
					dPos = 0;

					// Overestimate
					if (mc != 0) {
						uint_q_hat--;
						ulong sum = 0;

						do {
							sum = ((ulong)remainder [nPos]) + ((ulong)bi2.data [dPos]) + sum;
							remainder [nPos] = (uint)sum;
							sum >>= 32;
							dPos++; nPos++;
						} while (dPos < divisorLen);

					}

					quot.data [resultPos--] = (uint)uint_q_hat;

					pos--;
					j--;
				}

				quot.Normalize ();
				rem.Normalize ();
				BigInteger [] ret = new BigInteger [2] { quot, rem };

				if (shift != 0)
					ret [1] >>= shift;

				return ret;
			}
Beispiel #16
0
			public static BigInteger RightShift (BigInteger bi, int n)
			{
				if (n == 0) return new BigInteger (bi);

				int w = n >> 5;
				int s = n & ((1 << 5) - 1);

				BigInteger ret = new BigInteger (Sign.Positive, bi.length - (uint)w + 1);
				uint l = (uint)ret.data.Length - 1;

				if (s != 0) {

					uint x, carry = 0;

					while (l-- > 0) {
						x = bi.data [l + w];
						ret.data [l] = (x >> n) | carry;
						carry = x << (32 - n);
					}
				} else {
					while (l-- > 0)
						ret.data [l] = bi.data [l + w];

				}
				ret.Normalize ();
				return ret;
			}
Beispiel #17
0
            /// <summary>
            /// Adds two numbers with the same sign.
            /// </summary>
            /// <param name="bi1">A BigInteger</param>
            /// <param name="bi2">A BigInteger</param>
            /// <returns>bi1 + bi2</returns>
            public static BigInteger AddSameSign(BigInteger bi1, BigInteger bi2)
            {
                uint[] x, y;
                uint   yMax, xMax, i = 0;

                // x should be bigger
                if (bi1.length < bi2.length)
                {
                    x    = bi2.data;
                    xMax = bi2.length;
                    y    = bi1.data;
                    yMax = bi1.length;
                }
                else
                {
                    x    = bi1.data;
                    xMax = bi1.length;
                    y    = bi2.data;
                    yMax = bi2.length;
                }

                BigInteger result = new BigInteger(Sign.Positive, xMax + 1);

                uint[] r = result.data;

                ulong sum = 0;

                // Add common parts of both numbers
                do
                {
                    sum   = ((ulong)x[i]) + ((ulong)y[i]) + sum;
                    r[i]  = (uint)sum;
                    sum >>= 32;
                } while (++i < yMax);

                // Copy remainder of longer number while carry propagation is required
                bool carry = (sum != 0);

                if (carry)
                {
                    if (i < xMax)
                    {
                        do
                        {
                            carry = ((r[i] = x[i] + 1) == 0);
                        }while (++i < xMax && carry);
                    }

                    if (carry)
                    {
                        r[i]          = 1;
                        result.length = ++i;
                        return(result);
                    }
                }

                // Copy the rest
                if (i < xMax)
                {
                    do
                    {
                        r[i] = x[i];
                    }while (++i < xMax);
                }

                result.Normalize();
                return(result);
            }
Beispiel #18
0
            public void BarrettReduction(BigInteger x)
            {
                var  n         = _mod;
                uint k         = n.length,
                     kPlusOne  = k + 1,
                     kMinusOne = k - 1;

                // x < mod, so nothing to do.
                if (x.length < k)
                {
                    return;
                }

                //
                // Validate pointers
                //
                if (x.data.Length < x.length)
                {
                    throw new IndexOutOfRangeException("x out of range");
                }

                // q1 = x / b^ (k-1)
                // q2 = q1 * constant
                // q3 = q2 / b^ (k+1), Needs to be accessed with an offset of kPlusOne

                // TODO: We should the method in HAC p 604 to do this (14.45)
                var q3 = new BigInteger(Sign.Positive, x.length - kMinusOne + _constant.length);

                Kernel.Multiply(x.data, kMinusOne, x.length - kMinusOne, _constant.data, 0, _constant.length, q3.data, 0);

                // r1 = x mod b^ (k+1)
                // i.e. keep the lowest (k+1) words

                var lengthToCopy = (x.length > kPlusOne) ? kPlusOne : x.length;

                x.length = lengthToCopy;
                x.Normalize();

                // r2 = (q3 * n) mod b^ (k+1)
                // partial multiplication of q3 and n

                var r2 = new BigInteger(Sign.Positive, kPlusOne);

                Kernel.MultiplyMod2p32pmod(q3.data, (int)kPlusOne, (int)q3.length - (int)kPlusOne, n.data, 0, (int)n.length, r2.data, 0, (int)kPlusOne);

                r2.Normalize();

                if (r2 <= x)
                {
                    Kernel.MinusEq(x, r2);
                }
                else
                {
                    var val = new BigInteger(Sign.Positive, kPlusOne + 1);
                    val.data[kPlusOne] = 0x00000001;

                    Kernel.MinusEq(val, r2);
                    Kernel.PlusEq(x, val);
                }

                while (x >= n)
                {
                    Kernel.MinusEq(x, n);
                }
            }
Beispiel #19
0
			public static BigInteger DwordDiv(BigInteger n, uint d)
			{
				var ret = new BigInteger(Sign.Positive, n.length);

				ulong r = 0;
				uint i = n.length;

				while (i-- > 0)
				{
					r <<= 32;
					r |= n.data[i];
					ret.data[i] = (uint) (r/d);
					r %= d;
				}
				ret.Normalize();

				return ret;
			}
Beispiel #20
0
			/// <summary>
			/// Performs n / d and n % d in one operation.
			/// </summary>
			/// <param name="n">A BigInteger, upon exit this will hold n / d</param>
			/// <param name="d">The divisor</param>
			/// <returns>n % d</returns>
			public static uint SingleByteDivideInPlace (BigInteger n, uint d)
			{
				ulong r = 0;
				uint i = n.length;

				while (i-- > 0) {
					r <<= 32;
					r |= n.data [i];
					n.data [i] = (uint)(r / d);
					r %= d;
				}
				n.Normalize ();

				return (uint)r;
			}
Beispiel #21
0
			public static BigInteger [] DwordDivMod (BigInteger n, uint d)
			{
				BigInteger ret = new BigInteger (Sign.Positive , n.length);

				ulong r = 0;
				uint i = n.length;

				while (i-- > 0) {
					r <<= 32;
					r |= n.data [i];
					ret.data [i] = (uint)(r / d);
					r %= d;
				}
				ret.Normalize ();

				BigInteger rem = (uint)r;

				return new BigInteger [] {ret, rem};
			}
Beispiel #22
0
		public static BigInteger operator * (BigInteger bi1, BigInteger bi2)
		{
			if (bi1 == 0 || bi2 == 0) return 0;

			//
			// Validate pointers
			//
			if (bi1.data.Length < bi1.length) throw new IndexOutOfRangeException ("bi1 out of range");
			if (bi2.data.Length < bi2.length) throw new IndexOutOfRangeException ("bi2 out of range");

			BigInteger ret = new BigInteger (Sign.Positive, bi1.length + bi2.length);

			Kernel.Multiply (bi1.data, 0, bi1.length, bi2.data, 0, bi2.length, ret.data, 0);

			ret.Normalize ();
			return ret;
		}
Beispiel #23
0
			public static BigInteger LeftShift (BigInteger bi, int n)
			{
				if (n == 0) return new BigInteger (bi, bi.length + 1);

				int w = n >> 5;
				n &= ((1 << 5) - 1);

				BigInteger ret = new BigInteger (Sign.Positive, bi.length + 1 + (uint)w);

				uint i = 0, l = bi.length;
				if (n != 0) {
					uint x, carry = 0;
					while (i < l) {
						x = bi.data [i];
						ret.data [i + w] = (x << n) | carry;
						carry = x >> (32 - n);
						i++;
					}
					ret.data [i + w] = carry;
				} else {
					while (i < l) {
						ret.data [i + w] = bi.data [i];
						i++;
					}
				}

				ret.Normalize ();
				return ret;
			}
Beispiel #24
0
			private BigInteger OddPow (uint b, BigInteger exp)
			{
				exp.Normalize ();
				uint [] wkspace = new uint [mod.length << 1 + 1];

				BigInteger resultNum = Montgomery.ToMont ((BigInteger)b, this.mod);
				resultNum = new BigInteger (resultNum, mod.length << 1 +1);

				uint mPrime = Montgomery.Inverse (mod.data [0]);

				uint pos = (uint)exp.bitCount () - 2;

				//
				// We know that the first itr will make the val b
				//

				do {
					//
					// r = r ^ 2 % m
					//
					Kernel.SquarePositive(resultNum, ref wkspace);
					resultNum = Montgomery.Reduce(resultNum, mod, mPrime);

					if (exp.testBit(pos)) {

						//
						// r = r * b % m
						//

						uint u = 0;

						uint i = 0;
						ulong mc = 0;

						do {
							mc += (ulong)resultNum.data[u + i] * (ulong)b;
							resultNum.data[u + i] = (uint)mc;
							mc >>= 32;
						} while (++i < resultNum.length);

						if (resultNum.length < mod.length) {
							if (mc != 0) {
								resultNum.data[u + i] = (uint)mc;
								resultNum.length++;
								while (resultNum >= mod)
									Kernel.MinusEq(resultNum, mod);
							}
						} else if (mc != 0) {

							//
							// First, we estimate the quotient by dividing
							// the first part of each of the numbers. Then
							// we correct this, if necessary, with a subtraction.
							//

							uint cc = (uint)mc;

							// We would rather have this estimate overshoot,
							// so we add one to the divisor
							uint divEstimate = (uint)((((ulong)cc << 32) | (ulong)resultNum.data[u + i - 1]) /
								(mod.data[mod.length - 1] + 1));

							uint t;

							i = 0;
							mc = 0;
							do {
								mc += (ulong)mod.data[i] * (ulong)divEstimate;
								t = resultNum.data[u + i];
								resultNum.data[u + i] -= (uint)mc;
								mc >>= 32;
								if (resultNum.data[u + i] > t) mc++;
								i++;
							} while (i < resultNum.length);
							cc -= (uint)mc;

							if (cc != 0) {

								uint sc = 0, j = 0;
								uint[] s = mod.data;
								do {
									uint a = s[j];
									if (((a += sc) < sc) | ((resultNum.data[u + j] -= a) > ~a)) sc = 1;
									else sc = 0;
									j++;
								} while (j < resultNum.length);
								cc -= sc;
							}
							while (resultNum >= mod)
								Kernel.MinusEq(resultNum, mod);
						} else {
							while (resultNum >= mod)
								Kernel.MinusEq(resultNum, mod);
						}
					}
				} while (pos-- > 0);

				resultNum = Montgomery.Reduce (resultNum, mod, mPrime);
				return resultNum;

			}
Beispiel #25
0
			public static BigInteger MultiplyByDword (BigInteger n, uint f)
			{
				BigInteger ret = new BigInteger (Sign.Positive, n.length + 1);

				uint i = 0;
				ulong c = 0;

				do {
					c += (ulong)n.data [i] * (ulong)f;
					ret.data [i] = (uint)c;
					c >>= 32;
				} while (++i < n.length);
				ret.data [i] = (uint)c;
				ret.Normalize ();
				return ret;

			}
Beispiel #26
0
            public static void PlusEq(BigInteger bi1, BigInteger bi2)
            {
                uint[] x, y;
                uint   yMax, xMax, i = 0;
                bool   flag = false;

                // x should be bigger
                if (bi1.length < bi2.length)
                {
                    flag = true;
                    x    = bi2.data;
                    xMax = bi2.length;
                    y    = bi1.data;
                    yMax = bi1.length;
                }
                else
                {
                    x    = bi1.data;
                    xMax = bi1.length;
                    y    = bi2.data;
                    yMax = bi2.length;
                }

                uint[] r = bi1.data;

                ulong sum = 0;

                // Add common parts of both numbers
                do
                {
                    sum  += ((ulong)x[i]) + ((ulong)y[i]);
                    r[i]  = (uint)sum;
                    sum >>= 32;
                } while (++i < yMax);

                // Copy remainder of longer number while carry propagation is required
                bool carry = (sum != 0);

                if (carry)
                {
                    if (i < xMax)
                    {
                        do
                        {
                            carry = ((r[i] = x[i] + 1) == 0);
                        }while (++i < xMax && carry);
                    }

                    if (carry)
                    {
                        r[i]       = 1;
                        bi1.length = ++i;
                        return;
                    }
                }

                // Copy the rest
                if (flag && i < xMax - 1)
                {
                    do
                    {
                        r[i] = x[i];
                    }while (++i < xMax);
                }

                bi1.length = xMax + 1;
                bi1.Normalize();
            }
Beispiel #27
0
		/// <summary>
		/// Generates a new, random BigInteger of the specified length.
		/// </summary>
		/// <param name="bits">The number of bits for the new number.</param>
		/// <param name="rng">A random number generator to use to obtain the bits.</param>
		/// <returns>A random number of the specified length.</returns>
		public static BigInteger GenerateRandom (int bits, RandomNumberGenerator rng)
		{
			int dwords = bits >> 5;
			int remBits = bits & 0x1F;

			if (remBits != 0)
				dwords++;

			BigInteger ret = new BigInteger (Sign.Positive, (uint)dwords + 1);
			byte [] random = new byte [dwords << 2];

			rng.GetBytes (random);
			Buffer.BlockCopy (random, 0, ret.data, 0, (int)dwords << 2);

			if (remBits != 0) {
				uint mask = (uint)(0x01 << (remBits-1));
				ret.data [dwords-1] |= mask;

				mask = (uint)(0xFFFFFFFF >> (32 - remBits));
				ret.data [dwords-1] &= mask;
			}
			else
				ret.data [dwords-1] |= 0x80000000;

			ret.Normalize ();
			return ret;
		}
Beispiel #28
0
			private unsafe BigInteger EvenPow (uint b, BigInteger exp)
			{
				exp.Normalize ();
				uint [] wkspace = new uint [mod.length << 1 + 1];
				BigInteger resultNum = new BigInteger ((BigInteger)b, mod.length << 1 + 1);

				uint pos = (uint)exp.BitCount () - 2;

				//
				// We know that the first itr will make the val b
				//

				do {
					//
					// r = r ^ 2 % m
					//
					Kernel.SquarePositive (resultNum, ref wkspace);
					if (!(resultNum.length < mod.length))
						BarrettReduction (resultNum);

					if (exp.TestBit (pos)) {

						//
						// r = r * b % m
						//

						// TODO: Is Unsafe really speeding things up?
						fixed (uint* u = resultNum.data) {

							uint i = 0;
							ulong mc = 0;

							do {
								mc += (ulong)u [i] * (ulong)b;
								u [i] = (uint)mc;
								mc >>= 32;
							} while (++i < resultNum.length);

							if (resultNum.length < mod.length) {
								if (mc != 0) {
									u [i] = (uint)mc;
									resultNum.length++;
									while (resultNum >= mod)
										Kernel.MinusEq (resultNum, mod);
								}
							} else if (mc != 0) {

								//
								// First, we estimate the quotient by dividing
								// the first part of each of the numbers. Then
								// we correct this, if necessary, with a subtraction.
								//

								uint cc = (uint)mc;

								// We would rather have this estimate overshoot,
								// so we add one to the divisor
								uint divEstimate = (uint) ((((ulong)cc << 32) | (ulong) u [i -1]) /
									(mod.data [mod.length-1] + 1));

								uint t;

								i = 0;
								mc = 0;
								do {
									mc += (ulong)mod.data [i] * (ulong)divEstimate;
									t = u [i];
									u [i] -= (uint)mc;
									mc >>= 32;
									if (u [i] > t) mc++;
									i++;
								} while (i < resultNum.length);
								cc -= (uint)mc;

								if (cc != 0) {

									uint sc = 0, j = 0;
									uint [] s = mod.data;
									do {
										uint a = s [j];
										if (((a += sc) < sc) | ((u [j] -= a) > ~a)) sc = 1;
										else sc = 0;
										j++;
									} while (j < resultNum.length);
									cc -= sc;
								}
								while (resultNum >= mod)
									Kernel.MinusEq (resultNum, mod);
							} else {
								while (resultNum >= mod)
									Kernel.MinusEq (resultNum, mod);
							}
						}
					}
				} while (pos-- > 0);

				return resultNum;
			}