/// <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); }
/// <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; } } }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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 << (-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); }
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); }
/// <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); }
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); }
/// <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); }
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]; } }
/// <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++; } }
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++; } }
/// <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); }
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++; } }
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)); }
/// <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)); } } }
/// <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)); }
/// <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; } } }
/// <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); }
/// <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; } }
/// <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); }
/// <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); }
/// <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); }
/// <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; } }
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); }
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; } } }