Esempio n. 1
0
        /// <summary>
        /// Performs the same as GcdBinary(BigInteger, BigInteger)}, but with numbers of 63 bits,
        /// represented in positives values of long type.
        /// </summary>
        ///
        /// <param name="X">A positive number</param>
        /// <param name="Y">A positive number></param>
        ///
        /// <returns>Returns <c>Gcd(X, Y)</c></returns>
        internal static long GcdBinary(long X, long Y)
        {
            // (op1 > 0) and (op2 > 0)
            int lsb1      = IntUtils.NumberOfTrailingZeros(X);
            int lsb2      = IntUtils.NumberOfTrailingZeros(Y);
            int pow2Count = System.Math.Min(lsb1, lsb2);

            if (lsb1 != 0)
            {
                X = IntUtils.URShift(X, lsb1);
            }
            if (lsb2 != 0)
            {
                Y = IntUtils.URShift(Y, lsb2);
            }

            do
            {
                if (X >= Y)
                {
                    X -= Y;
                    X  = IntUtils.URShift(X, IntUtils.NumberOfTrailingZeros(X));
                }
                else
                {
                    Y -= X;
                    Y  = IntUtils.URShift(Y, IntUtils.NumberOfTrailingZeros(Y));
                }
            } while (X != 0);

            return(Y << pow2Count);
        }
Esempio n. 2
0
        /// <summary>
        /// Create a nxn random lower triangular matrix
        /// </summary>
        ///
        /// <param name="N">Number of rows (and columns)</param>
        /// <param name="SecRnd">Source of randomness</param>
        private void AssignRandomLowerTriangularMatrix(int N, IRandom SecRnd)
        {
            RowCount    = N;
            ColumnCount = N;
            _length     = IntUtils.URShift((N + 31), 5);
            _matrix     = ArrayUtils.CreateJagged <int[][]>(RowCount, _length);
            for (int i = 0; i < RowCount; i++)
            {
                int q = IntUtils.URShift(i, 5);
                int r = i & 0x1f;
                int s = 31 - r;
                r = 1 << r;

                for (int j = 0; j < q; j++)
                {
                    _matrix[i][j] = SecRnd.Next();
                }

                _matrix[i][q] = (IntUtils.URShift(SecRnd.Next(), s)) | r;

                for (int j = q + 1; j < _length; j++)
                {
                    _matrix[i][j] = 0;
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Compute exponentiation of a^k
        /// </summary>
        ///
        /// <param name="A">The field element A</param>
        /// <param name="K">The K degree</param>
        ///
        /// <returns>The sum: <c>a pow k</c></returns>
        public int Exp(int A, int K)
        {
            if (A == 0)
            {
                return(0);
            }
            if (A == 1)
            {
                return(1);
            }

            int result = 1;

            if (K < 0)
            {
                A = Inverse(A);
                K = -K;
            }
            while (K != 0)
            {
                if ((K & 1) == 1)
                {
                    result = Multiply(result, A);
                }

                A = Multiply(A, A);
                K = IntUtils.URShift(K, 1);
            }

            return(result);
        }
Esempio n. 4
0
        /// <summary>
        /// Compute the product of two polynomials modulo a third polynomial
        /// </summary>
        ///
        /// <param name="A">The first polynomial</param>
        /// <param name="B">The second polynomial</param>
        /// <param name="R">The reduction polynomial</param>
        ///
        /// <returns>Returns <c>a * b mod r</c></returns>
        public static int ModMultiply(int A, int B, int R)
        {
            int result = 0;
            int p      = Remainder(A, R);
            int q      = Remainder(B, R);

            if (q != 0)
            {
                int d = 1 << Degree(R);

                while (p != 0)
                {
                    byte pMod2 = (byte)(p & 0x01);
                    if (pMod2 == 1)
                    {
                        result ^= q;
                    }
                    p   = IntUtils.URShift(p, 1);
                    q <<= 1;
                    if (q >= d)
                    {
                        q ^= R;
                    }
                }
            }
            return(result);
        }
Esempio n. 5
0
        /// <summary>
        /// Returns encoded matrix, i.e., this matrix in byte array form
        /// </summary>
        ///
        /// <returns>The encoded matrix</returns>
        public override byte[] GetEncoded()
        {
            int n = IntUtils.URShift((ColumnCount + 7), 3);

            n *= RowCount;
            n += 8;
            byte[] enc = new byte[n];

            LittleEndian.IntToOctets(RowCount, enc, 0);
            LittleEndian.IntToOctets(ColumnCount, enc, 4);
            // number of "full" integer
            int q = IntUtils.URShift(ColumnCount, 5);
            // number of bits in non-full integer
            int r     = ColumnCount & 0x1f;
            int count = 8;

            for (int i = 0; i < RowCount; i++)
            {
                for (int j = 0; j < q; j++, count += 4)
                {
                    LittleEndian.IntToOctets(_matrix[i][j], enc, count);
                }
                for (int j = 0; j < r; j += 8)
                {
                    enc[count++] = (byte)((IntUtils.URShift(_matrix[i][q], j)) & 0xff);
                }
            }

            return(enc);
        }
Esempio n. 6
0
        /// <summary>
        /// Returns a byte array encoding of this matrix
        /// </summary>
        ///
        /// <returns>The encoded GF2mMatrix</returns>
        public override byte[] GetEncoded()
        {
            int d     = 8;
            int count = 1;

            while (FieldG.Degree > d)
            {
                count++;
                d += 8;
            }

            byte[] bf = new byte[this.RowCount * this.ColumnCount * count + 4];
            bf[0] = (byte)(this.RowCount & 0xff);
            bf[1] = (byte)((this.RowCount >> 8) & 0xff);
            bf[2] = (byte)((this.RowCount >> 16) & 0xff);
            bf[3] = (byte)((this.RowCount >> 24) & 0xff);

            count = 4;
            for (int i = 0; i < this.RowCount; i++)
            {
                for (int j = 0; j < this.ColumnCount; j++)
                {
                    for (int jj = 0; jj < d; jj += 8)
                    {
                        bf[count++] = (byte)(IntUtils.URShift(MatrixN[i][j], jj));
                    }
                }
            }

            return(bf);
        }
Esempio n. 7
0
        /// <summary>
        /// A random number is generated until a probable prime number is found
        /// </summary>
        internal static BigInteger ConsBigInteger(int BitLength, int Certainty, SecureRandom Rnd)
        {
            // PRE: bitLength >= 2;
            // For small numbers get a random prime from the prime table
            if (BitLength <= 10)
            {
                int[] rp = m_offsetPrimes[BitLength];
                return(m_biPrimes[rp[0] + Rnd.NextInt32(rp[1])]);
            }
            int        shiftCount = (-BitLength) & 31;
            int        last       = (BitLength + 31) >> 5;
            BigInteger n          = new BigInteger(1, last, new int[last]);

            last--;
            do
            {// To fill the array with random integers
                for (int i = 0; i < n.m_numberLength; i++)
                {
                    n.m_digits[i] = Rnd.Next();
                }

                // To fix to the correct bitLength
                // n.digits[last] |= 0x80000000;
                n.m_digits[last] |= int.MinValue;
                n.m_digits[last]  = IntUtils.URShift(n.m_digits[last], shiftCount);
                // To create an odd number
                n.m_digits[0] |= 1;
            } while (!IsProbablePrime(n, Certainty));

            return(n);
        }
Esempio n. 8
0
        /// <summary>
        /// Compute the square root of this element
        /// </summary>
        public override void SquareRootThis()
        {
            long[] pol = GetElement();
            int    f   = m_Length - 1;
            int    b   = m_Bit - 1;
            // Shift the coefficients one bit to the right.
            long TWOTOMAXLONGM1 = _mBitmask[MAXLONG - 1];
            bool old, now;

            old = (pol[0] & 1) != 0;

            for (int i = f; i >= 0; i--)
            {
                now    = (pol[i] & 1) != 0;
                pol[i] = IntUtils.URShift(pol[i], 1);

                if (old)
                {
                    if (i == f)
                    {
                        pol[i] ^= _mBitmask[b];
                    }
                    else
                    {
                        pol[i] ^= TWOTOMAXLONGM1;
                    }
                }
                old = now;
            }
            Assign(pol);
        }
Esempio n. 9
0
        /// <summary>
        /// Returns a new BigInteger whose value is <c>this >> N</c>
        /// <para>For negative arguments, the result is also negative.
        /// The shift distance may be negative which means that this is shifted left.
        /// </para>
        /// </summary>
        ///
        /// <param name="Result">The result</param>
        /// <param name="ResultLen">The result length</param>
        /// <param name="Value">The source BigIntger</param>
        /// <param name="IntCount">The number integers</param>
        /// <param name="N">Shift distance</param>
        ///
        /// <returns>this >> N, if N >= 0; this &lt;&lt; (-n) otherwise</returns>
        internal static bool ShiftRight(int[] Result, int ResultLen, int[] Value, int IntCount, int N)
        {
            int  i;
            bool allZero = true;

            for (i = 0; i < IntCount; i++)
            {
                allZero &= Value[i] == 0;
            }
            if (N == 0)
            {
                Array.Copy(Value, IntCount, Result, 0, ResultLen);
                i = ResultLen;
            }
            else
            {
                int leftShiftCount = 32 - N;

                allZero &= (Value[i] << leftShiftCount) == 0;
                for (i = 0; i < ResultLen - 1; i++)
                {
                    Result[i] = IntUtils.URShift(Value[i + IntCount], N) |
                                (Value[i + IntCount + 1] << leftShiftCount);
                }
                Result[i] = IntUtils.URShift(Value[i + IntCount], N);
                i++;
            }

            return(allZero);
        }
Esempio n. 10
0
        private static int[] Square(int[] X, int XLen, int[] Result)
        {
            long carry;

            for (int i = 0; i < XLen; i++)
            {
                carry = 0;
                for (int j = i + 1; j < XLen; j++)
                {
                    carry         = UnsignedMultAddAdd(X[i], X[j], Result[i + j], (int)carry);
                    Result[i + j] = (int)carry;
                    carry         = IntUtils.URShift(carry, 32);
                }
                Result[i + XLen] = (int)carry;
            }

            BitLevel.ShiftLeftOneBit(Result, Result, XLen << 1);

            carry = 0;
            for (int i = 0, index = 0; i < XLen; i++, index++)
            {
                carry         = UnsignedMultAddAdd(X[i], X[i], Result[index], (int)carry);
                Result[index] = (int)carry;
                carry         = IntUtils.URShift(carry, 32);
                index++;
                carry        += Result[index] & 0xFFFFFFFFL;
                Result[index] = (int)carry;
                carry         = IntUtils.URShift(carry, 32);
            }
            return(Result);
        }
Esempio n. 11
0
        /// <summary>
        /// Decodes a <c>byte</c> array encoded with EncodeModQ(int[], int)} back to an <c>int</c> array.
        /// <para><c>N</c> is the number of coefficients. <c>Q</c> must be a power of <c>2</c>.
        /// Ignores any excess bytes.</para>
        /// </summary>
        ///
        /// <param name="Data">Data an encoded ternary polynomial</param>
        /// <param name="N">The number of coefficients</param>
        /// <param name="Q">The modulus</param>
        ///
        /// <returns>Returns an array containing <c>N</c> coefficients between <c>0</c> and <c>q-1</c></returns>
        public static int[] DecodeModQ(byte[] Data, int N, int Q)
        {
            int[] coeffs       = new int[N];
            int   bitsPerCoeff = 31 - IntUtils.NumberOfLeadingZeros(Q);
            int   mask         = IntUtils.URShift(-1, (32 - bitsPerCoeff)); // for truncating values to bitsPerCoeff bits
            int   byteIndex    = 0;
            int   bitIndex     = 0;                                         // next bit in data[byteIndex]
            int   coeffBuf     = 0;                                         // contains (bitIndex) bits
            int   coeffBits    = 0;                                         // length of coeffBuf
            int   coeffIndex   = 0;                                         // index into coeffs

            while (coeffIndex < N)
            {
                // copy bitsPerCoeff or more into coeffBuf
                while (coeffBits < bitsPerCoeff)
                {
                    coeffBuf  += (Data[byteIndex] & 0xFF) << coeffBits;
                    coeffBits += 8 - bitIndex;
                    byteIndex++;
                    bitIndex = 0;
                }

                // low bitsPerCoeff bits = next coefficient
                coeffs[coeffIndex] = coeffBuf & mask;
                coeffIndex++;
                coeffBuf   = IntUtils.URShift(coeffBuf, bitsPerCoeff);
                coeffBits -= bitsPerCoeff;
            }

            return(coeffs);
        }
Esempio n. 12
0
        private static BigInteger MultiplyPAP(BigInteger X, BigInteger Y)
        {
            // Multiplies two BigIntegers. Implements traditional scholar algorithm described by Knuth.
            // PRE: a >= b
            int aLen      = X.m_numberLength;
            int bLen      = Y.m_numberLength;
            int resLength = aLen + bLen;
            int resSign   = (X.m_sign != Y.m_sign) ? -1 : 1;

            // A special case when both numbers don't exceed int
            if (resLength == 2)
            {
                long val     = UnsignedMultAddAdd(X.m_digits[0], Y.m_digits[0], 0, 0);
                int  valueLo = (int)val;
                int  valueHi = (int)IntUtils.URShift(val, 32);

                return((valueHi == 0) ?
                       new BigInteger(resSign, valueLo) :
                       new BigInteger(resSign, 2, new int[] { valueLo, valueHi }));
            }
            int[] aDigits   = X.m_digits;
            int[] bDigits   = Y.m_digits;
            int[] resDigits = new int[resLength];
            // Common case
            MultiplyArraysPAP(aDigits, aLen, bDigits, bLen, resDigits);
            BigInteger result = new BigInteger(resSign, resLength, resDigits);

            result.CutOffLeadingZeroes();

            return(result);
        }
Esempio n. 13
0
        /// <summary>
        /// Multiplies a number by a positive integer
        /// </summary>
        ///
        /// <param name="X">An arbitrary BigInteger</param>
        /// <param name="Factor">A positive int number</param>
        ///
        /// <returns>X * Factor</returns>
        internal static BigInteger MultiplyByPositiveInt(BigInteger X, int Factor)
        {
            int resSign = X.m_sign;

            if (resSign == 0)
            {
                return(BigInteger.Zero);
            }

            int aNumberLength = X.m_numberLength;

            int[] aDigits = X.m_digits;

            if (aNumberLength == 1)
            {
                long res   = UnsignedMultAddAdd(aDigits[0], Factor, 0, 0);
                int  resLo = (int)res;
                int  resHi = (int)IntUtils.URShift(res, 32);

                return((resHi == 0) ?
                       new BigInteger(resSign, resLo) :
                       new BigInteger(resSign, 2, new int[] { resLo, resHi }));
            }
            // Common case
            int resLength = aNumberLength + 1;

            int[] resDigits = new int[resLength];

            resDigits[aNumberLength] = MultiplyByInt(resDigits, aDigits, aNumberLength, Factor);
            BigInteger result = new BigInteger(resSign, resLength, resDigits);

            result.CutOffLeadingZeroes();

            return(result);
        }
Esempio n. 14
0
        private static void MonReduction(int[] Result, BigInteger Modulus, int N2)
        {
            // res + m*modulus_digits
            int[] modulus_digits = Modulus.m_digits;
            int   modulusLen     = Modulus.m_numberLength;
            long  outerCarry     = 0;

            for (int i = 0; i < modulusLen; i++)
            {
                long innnerCarry = 0;
                int  m           = (int)Multiplication.UnsignedMultAddAdd(Result[i], N2, 0, 0);
                for (int j = 0; j < modulusLen; j++)
                {
                    innnerCarry   = Multiplication.UnsignedMultAddAdd(m, modulus_digits[j], Result[i + j], (int)innnerCarry);
                    Result[i + j] = (int)innnerCarry;
                    innnerCarry   = IntUtils.URShift(innnerCarry, 32);
                }

                outerCarry            += (Result[i + modulusLen] & 0xFFFFFFFFL) + innnerCarry;
                Result[i + modulusLen] = (int)outerCarry;
                outerCarry             = IntUtils.URShift(outerCarry, 32);
            }

            Result[modulusLen << 1] = (int)outerCarry;

            // res / r
            for (int j = 0; j < modulusLen + 1; j++)
            {
                Result[j] = Result[j + modulusLen];
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Adds two numbers, <c>A</c> and <c>B</c>, after shifting <c>B</c> by <c>numElements</c> elements.
        /// </summary>
        ///
        /// <param name="A">A number in base 2^32 starting with the lowest digit</param>
        /// <param name="B">A number in base 2^32 starting with the lowest digit</param>
        /// <param name="NumElements">The shift amount in bits</param>
        ///
        /// <remarks>
        /// Both numbers are given as <c>int</c> arrays and must be positive numbers (meaning they are interpreted as unsigned).
        /// The result is returned in the first argument. If any elements of B are shifted outside the valid range for <c>A</c>, they are dropped.
        /// </remarks>
        public static void AddShifted(int[] A, int[] B, int NumElements)
        {
            bool carry = false;
            int  i     = 0;

            while (i < Math.Min(B.Length, A.Length - NumElements))
            {
                int ai  = A[i + NumElements];
                int sum = ai + B[i];

                if (carry)
                {
                    sum++;
                }

                carry = (IntUtils.URShift(sum, 31) < IntUtils.URShift(ai, 31) + IntUtils.URShift(B[i], 31));   // carry if signBit(sum) < signBit(a)+signBit(b)
                A[i + NumElements] = sum;
                i++;
            }

            while (carry)
            {
                A[i + NumElements]++;
                carry = A[i + NumElements] == 0;
                i++;
            }
        }
Esempio n. 16
0
        private void AddShifted(int[] A, int[] B, int NumElements)
        {
            // drops elements of b that are shifted outside the valid range
            bool carry = false;
            int  i     = 0;

            while (i < Math.Min(B.Length, A.Length - NumElements))
            {
                int ai  = A[i + NumElements];
                int sum = ai + B[i];

                if (carry)
                {
                    sum++;
                }

                carry = (IntUtils.URShift(sum, 31) < IntUtils.URShift(ai, 31) + IntUtils.URShift(B[i], 31));   // carry if signBit(sum) < signBit(a)+signBit(b)
                A[i + NumElements] = sum;
                i++;
            }

            i += NumElements;
            while (carry)
            {
                A[i]++;
                carry = A[i] == 0;
                i++;
            }
        }
Esempio n. 17
0
        /// <remarks>
        /// Subtracts two positive numbers (meaning they are interpreted as unsigned) that are given as
        /// int arrays and returns the result in a new array.
        /// </remarks>
        private static int[] SubExpand(int[] A, int[] B)
        {
            int[] c     = A.CopyOf(Math.Max(A.Length, B.Length));
            bool  carry = false;
            int   i     = 0;

            while (i < Math.Min(B.Length, A.Length))
            {
                int diff = A[i] - B[i];
                if (carry)
                {
                    diff--;
                }

                // carry if signBit(diff) > signBit(a)-signBit(b)
                carry = (IntUtils.URShift(diff, 31) > IntUtils.URShift(A[i], 31) - IntUtils.URShift(B[i], 31));
                c[i]  = diff;
                i++;
            }
            while (carry)
            {
                c[i]--;
                carry = c[i] == -1;
                i++;
            }

            return(c);
        }
Esempio n. 18
0
        private void SubShifted(int[] A, int[] B, int NumElements)
        {
            bool carry = false;
            int  i     = 0;

            // drops elements of b that are shifted outside the valid range
            while (i < Math.Min(B.Length, A.Length - NumElements))
            {
                int ai   = A[i + NumElements];
                int diff = ai - B[i];

                if (carry)
                {
                    diff--;
                }

                carry = (IntUtils.URShift(diff, 31) > IntUtils.URShift(A[i], 31) - IntUtils.URShift(B[i], 31));   // carry if signBit(diff) > signBit(a)-signBit(b)
                A[i + NumElements] = diff;
                i++;
            }

            i += NumElements;
            while (carry)
            {
                A[i]--;
                carry = A[i] == -1;
                i++;
            }
        }
Esempio n. 19
0
        private static long DivideLongByBillion(long N)
        {
            long quot;
            long rem;

            if (N >= 0)
            {
                long bLong = 1000000000L;
                quot = (N / bLong);
                rem  = (N % bLong);
            }
            else
            {
                /*
                 * Make the dividend positive shifting it right by 1 bit then get
                 * the quotient an remainder and correct them properly
                 */
                long aPos = IntUtils.URShift(N, 1);
                long bPos = IntUtils.URShift(1000000000L, 1);
                quot = aPos / bPos;
                rem  = aPos % bPos;
                // double the remainder and add 1 if 'a' is odd
                rem = (rem << 1) + (N & 1);
            }
            return((rem << 32) | (quot & 0xFFFFFFFFL));
        }
Esempio n. 20
0
        /// <summary>
        /// Reads BitLenB bits from <c>B</c>, starting at array index
        /// <c>StartB</c>, and copies them into <c>A</c>, starting at bit
        /// <c>BitLenA</c>. The result is returned in <c>A</c>.
        /// </summary>
        ///
        /// <param name="A">Array A</param>
        /// <param name="BitLenA">Array A bit length</param>
        /// <param name="B">Array B</param>
        /// <param name="StartB">B starting position</param>
        /// <param name="BitLenB">Array B bit length</param>
        public static void AppendBits(int[] A, int BitLenA, int[] B, int StartB, int BitLenB)
        {
            int aIdx  = BitLenA / 32;
            int bit32 = BitLenA % 32;

            for (int i = StartB; i < (StartB + BitLenB) / 32; i++)
            {
                if (bit32 > 0)
                {
                    A[aIdx] |= B[i] << bit32;
                    aIdx++;
                    A[aIdx] = IntUtils.URShift(B[i], (32 - bit32));
                }
                else
                {
                    A[aIdx] = B[i];
                    aIdx++;
                }
            }

            if (BitLenB % 32 > 0)
            {
                int bIdx = BitLenB / 32;
                int bi   = B[StartB + bIdx];

                bi      &= IntUtils.URShift(-1, (32 - BitLenB));
                A[aIdx] |= bi << bit32;

                if (bit32 + (BitLenB % 32) > 32)
                {
                    A[aIdx + 1] = IntUtils.URShift(bi, (32 - bit32));
                }
            }
        }
Esempio n. 21
0
        /// <summary>
        /// Rewrite this vector as a vector over <c>GF(2^m)</c> with <c>t</c> elements
        /// </summary>
        ///
        /// <param name="Field">The finite field <c>GF(2<sup>m</sup>)</c></param>
        ///
        /// <returns>Returns the converted vector over <c>GF(2<sup>m</sup>)</c></returns>
        public GF2mVector ToExtensionFieldVector(GF2mField Field)
        {
            int m = Field.Degree;

            if ((Length % m) != 0)
            {
                throw new ArithmeticException("GF2Vector: Conversion is impossible!");
            }

            int t = Length / m;

            int[] result = new int[t];
            int   count  = 0;

            for (int i = t - 1; i >= 0; i--)
            {
                for (int j = Field.Degree - 1; j >= 0; j--)
                {
                    int q = IntUtils.URShift(count, 5);
                    int r = count & 0x1f;

                    int e = (IntUtils.URShift(m_elements[q], r)) & 1;
                    if (e == 1)
                    {
                        result[i] ^= 1 << j;
                    }

                    count++;
                }
            }
            return(new GF2mVector(Field, result));
        }
Esempio n. 22
0
        /// <summary>
        /// Adds two positive numbers (meaning they are interpreted as unsigned) modulo 2^2^N+1,
        /// where N is <c>A.Length*32/2</c>; in other words, n is half the number of bits in <c>A</c>.
        /// <para>Both input values are given as <c>int</c> arrays; they must be the same length.
        /// The result is returned in the first argument.</para>
        /// </summary>
        ///
        /// <param name="A">A number in base 2^32 starting with the lowest digit; the length must be a power of 2</param>
        /// <param name="B">A number in base 2^32 starting with the lowest digit; the length must be a power of 2</param>
        public static void AddModFn(int[] A, int[] B)
        {
            bool carry = false;

            for (int i = 0; i < A.Length; i++)
            {
                int sum = A[i] + B[i];

                if (carry)
                {
                    sum++;
                }

                carry = (IntUtils.URShift(sum, 31) < IntUtils.URShift(A[i], 31) + IntUtils.URShift(B[i], 31));   // carry if signBit(sum) < signBit(a)+signBit(b)
                A[i]  = sum;
            }

            // take a mod Fn by adding any remaining carry bit to the lowest bit;
            // since Fn ≡ 1 (mod 2^n), it suffices to add 1
            int j = 0;

            while (carry)
            {
                int sum = A[j] + 1;

                A[j]  = sum;
                carry = sum == 0;
                j++;

                if (j >= A.Length)
                {
                    j = 0;
                }
            }
        }
Esempio n. 23
0
        /// <summary>
        /// Return the resultant of division two polynomials
        /// </summary>
        ///
        /// <param name="P">The P polynomial</param>
        /// <param name="Q">The Q polynomial</param>
        ///
        /// <returns>The rest value</returns>
        public static int Rest(long P, int Q)
        {
            long p1 = P;

            if (Q == 0)
            {
                return(0);
            }

            long q1 = Q & 0x00000000ffffffffL;

            while ((IntUtils.URShift(p1, 32)) != 0)
            {
                p1 ^= q1 << (Degree(p1) - Degree(q1));
            }

            int result = (int)(p1 & 0xffffffff);

            while (Degree(result) >= Degree(Q))
            {
                result ^= Q << (Degree(result) - Degree(Q));
            }

            return(result);
        }
Esempio n. 24
0
        /// <summary>
        /// Subtracts two positive numbers (meaning they are interpreted as unsigned) modulo 2^numBits.
        /// <para>Both input values are given as <c>int</c> arrays.
        /// The result is returned in the first argument.</para>
        /// </summary>
        ///
        /// <param name="A">A number in base 2^32 starting with the lowest digit</param>
        /// <param name="B">A number in base 2^32 starting with the lowest digit</param>
        /// <param name="NumBits">The number of bits to shift</param>
        public static void SubModPow2(int[] A, int[] B, int NumBits)
        {
            int  numElements = (NumBits + 31) / 32;
            bool carry       = false;
            int  i;

            for (i = 0; i < numElements; i++)
            {
                int diff = A[i] - B[i];
                if (carry)
                {
                    diff--;
                }

                carry = (IntUtils.URShift(diff, 31) > IntUtils.URShift(A[i], 31) - IntUtils.URShift(B[i], 31));   // carry if signBit(diff) > signBit(a)-signBit(b)
                A[i]  = diff;
            }

            A[i - 1] &= IntUtils.URShift(-1, 32 - (NumBits % 32));

            for (; i < A.Length; i++)
            {
                A[i] = 0;
            }
        }
Esempio n. 25
0
        /// <summary>
        /// Compute the product of this matrix and a permutation matrix which is generated from an n-permutation
        /// </summary>
        ///
        /// <param name="P">The permutation</param>
        ///
        /// <returns>Returns GF2Matrix <c>this*P</c></returns>
        public override Matrix RightMultiply(Permutation P)//3
        {
            int[] pVec = P.GetVector();
            if (pVec.Length != ColumnCount)
            {
                throw new ArithmeticException("GF2Matrix: Length mismatch!");
            }

            GF2Matrix result = new GF2Matrix(RowCount, ColumnCount);

            for (int i = ColumnCount - 1; i >= 0; i--)
            {
                int q  = IntUtils.URShift(i, 5);
                int r  = i & 0x1f;
                int pq = IntUtils.URShift(pVec[i], 5);
                int pr = pVec[i] & 0x1f;

                for (int j = RowCount - 1; j >= 0; j--)
                {
                    result._matrix[j][q] |= ((IntUtils.URShift(_matrix[j][pq], pr)) & 1) << r;
                }
            }

            return(result);
        }
Esempio n. 26
0
        /// <summary>
        /// Adds two positive numbers (meaning they are interpreted as unsigned) that are given as
        /// int arrays and returns the result in a new array. The result may be one longer
        /// than the input due to a carry.
        /// </summary>
        ///
        /// <param name="A">A number in base 2^32 starting with the lowest digit</param>
        /// <param name="B">A number in base 2^32 starting with the lowest digit</param>
        ///
        /// <returns>The sum</returns>
        private static int[] AddExpand(int[] A, int[] B)
        {
            int[] c     = A.CopyOf(Math.Max(A.Length, B.Length));
            bool  carry = false;
            int   i     = 0;

            while (i < Math.Min(B.Length, A.Length))
            {
                int sum = A[i] + B[i];
                if (carry)
                {
                    sum++;
                }

                carry = (IntUtils.URShift(sum, 31) < IntUtils.URShift(A[i], 31) + IntUtils.URShift(B[i], 31));   // carry if signBit(sum) < signBit(a)+signBit(b)
                c[i]  = sum;
                i++;
            }
            while (carry)
            {
                if (i == c.Length)
                {
                    c = c.CopyOf(c.Length + 1);
                }

                c[i]++;
                carry = c[i] == 0;
                i++;
            }
            return(c);
        }
Esempio n. 27
0
            /// <summary>
            /// Returns the last <c>NumBits</c> bits from the end of the bit string
            /// </summary>
            ///
            /// <param name="NumBits">Number of bits to return</param>
            ///
            /// <returns>A new <c>BitString</c> of length <c>numBits</c></returns>
            public BitString GetTrailing(int NumBits)
            {
                BitString newStr = new BitString();

                newStr._numBytes = (NumBits + 7) / 8;
                newStr.Bytes     = new byte[newStr._numBytes];

                for (int i = 0; i < newStr._numBytes; i++)
                {
                    newStr.Bytes[i] = Bytes[i];
                }

                newStr._lastByteBits = NumBits % 8;

                if (newStr._lastByteBits == 0)
                {
                    newStr._lastByteBits = 8;
                }
                else
                {
                    int s = 32 - newStr._lastByteBits;
                    newStr.Bytes[newStr._numBytes - 1] = (byte)(IntUtils.URShift((newStr.Bytes[newStr._numBytes - 1] << s), s));
                }

                return(newStr);
            }
Esempio n. 28
0
        /// <summary>
        /// Adds two positive numbers (meaning they are interpreted as unsigned) modulo 2^numBits.
        /// Both input values are given as int arrays. The result is returned in the first argument.
        /// </summary>
        /// <param name="A">A number in base 2^32 starting with the lowest digit</param>
        /// <param name="B">A number in base 2^32 starting with the lowest digit</param>
        /// <param name="NumBits">The modulo bit size</param>
        private static void AddModPow2(int[] A, int[] B, int NumBits)
        {
            int  numElements = (NumBits + 31) / 32;
            bool carry       = false;
            int  i;

            for (i = 0; i < numElements; i++)
            {
                int sum = A[i] + B[i];
                if (carry)
                {
                    sum++;
                }

                // carry if signBit(sum) < signBit(a)+signBit(b)
                carry = (IntUtils.URShift(sum, 31) < IntUtils.URShift(A[i], 31) + IntUtils.URShift(B[i], 31));
                A[i]  = sum;
            }

            A[i - 1] &= IntUtils.URShift(-1, 32 - (NumBits % 32));

            for (; i < A.Length; i++)
            {
                A[i] = 0;
            }
        }
Esempio n. 29
0
        private static String PolyToString(int P)
        {
            String str = "";

            if (P == 0)
            {
                str = "0";
            }
            else
            {
                byte b = (byte)(P & 0x01);
                if (b == 1)
                {
                    str = "1";
                }

                P = IntUtils.URShift(P, 1);
                int i = 1;

                while (P != 0)
                {
                    b = (byte)(P & 0x01);
                    if (b == 1)
                    {
                        str = str + "+x^" + i;
                    }

                    P = IntUtils.URShift(P, 1);
                    i++;
                }
            }
            return(str);
        }
Esempio n. 30
0
        void rearrange(int[] a_0, int[] a_1)
        {
            int i;
            int bit1, bit2, bit3, bit4, bit5, bit6, bit7;
            int swp_index;

            int u1, u2;

            for (i = 0; i < Globals.M / 2; i++)
            {
                bit1 = i % 2;
                bit2 = IntUtils.URShift(i, 1) % 2;
                bit3 = IntUtils.URShift(i, 2) % 2;
                bit4 = IntUtils.URShift(i, 3) % 2;
                bit5 = IntUtils.URShift(i, 4) % 2;
                bit6 = IntUtils.URShift(i, 5) % 2;
                bit7 = IntUtils.URShift(i, 6) % 2;

                swp_index = bit1 * 64 + bit2 * 32 + bit3 * 16 + bit4 * 8 + bit5 * 4 + bit6 * 2 + bit7;

                if (swp_index > i)
                {
                    u1 = a_0[i];
                    u2 = a_1[i];

                    a_0[i] = a_0[swp_index];
                    a_1[i] = a_1[swp_index];

                    a_0[swp_index] = u1;
                    a_1[swp_index] = u2;
                }
            }
        }