public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) { LongArray ax = this.x, bx = ((F2mFieldElement)b).x, xx = ((F2mFieldElement)x).x, yx = ((F2mFieldElement)y).x; LongArray ab = ax.Multiply(bx, m, ks); LongArray xy = xx.Multiply(yx, m, ks); if (ab == ax || ab == bx) { ab = (LongArray)ab.Copy(); } ab.AddShiftedByWords(xy, 0); ab.Reduce(m, ks); return(new F2mFieldElement(m, ks, ab)); }
public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) { LongArray ax = this.x, xx = ((F2mFieldElement)x).x, yx = ((F2mFieldElement)y).x; LongArray aa = ax.Square(m, ks); LongArray xy = xx.Multiply(yx, m, ks); if (aa == ax) { aa = (LongArray)aa.Copy(); } aa.AddShiftedByWords(xy, 0); aa.Reduce(m, ks); return(new F2mFieldElement(m, ks, aa)); }
public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) { LongArray array = this.x; LongArray other = ((F2mFieldElement)b).x; LongArray array3 = ((F2mFieldElement)x).x; LongArray array4 = ((F2mFieldElement)y).x; LongArray array5 = array.Multiply(other, this.m, this.ks); LongArray array6 = array3.Multiply(array4, this.m, this.ks); if ((array5 == array) || (array5 == other)) { array5 = array5.Copy(); } array5.AddShiftedByWords(array6, 0); array5.Reduce(this.m, this.ks); return(new F2mFieldElement(this.m, this.ks, array5)); }
public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) { LongArray longArray = this.x; LongArray longArray2 = ((F2mFieldElement)b).x; LongArray longArray3 = ((F2mFieldElement)x).x; LongArray other = ((F2mFieldElement)y).x; LongArray longArray4 = longArray.Multiply(longArray2, m, ks); LongArray other2 = longArray3.Multiply(other, m, ks); if (longArray4 == longArray || longArray4 == longArray2) { longArray4 = longArray4.Copy(); } longArray4.AddShiftedByWords(other2, 0); longArray4.Reduce(m, ks); return(new F2mFieldElement(m, ks, longArray4)); }
private void AddShiftedByBitsSafe(LongArray other, int otherDegree, int bits) { int num = (int)((uint)(otherDegree + 63) >> 6); int num2 = (int)((uint)bits >> 6); int num3 = bits & 0x3F; if (num3 == 0) { Add(m_ints, num2, other.m_ints, 0, num); return; } long num4 = AddShiftedUp(m_ints, num2, other.m_ints, 0, num, num3); if (num4 != 0) { long[] ints; long[] array = (ints = m_ints); int num5 = num + num2; global::System.IntPtr intPtr = (global::System.IntPtr)num5; array[num5] = ints[(long)intPtr] ^ num4; } }
public LongArray ModMultiply(LongArray other, int m, int[] ks) { /* * Find out the degree of each argument and handle the zero cases */ int aDeg = Degree(); if (aDeg == 0) { return this; } int bDeg = other.Degree(); if (bDeg == 0) { return other; } /* * Swap if necessary so that A is the smaller argument */ LongArray A = this, B = other; if (aDeg > bDeg) { A = other; B = this; int tmp = aDeg; aDeg = bDeg; bDeg = tmp; } /* * Establish the word lengths of the arguments and result */ int aLen = (int)((uint)(aDeg + 63) >> 6); int bLen = (int)((uint)(bDeg + 63) >> 6); int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6); if (aLen == 1) { long a0 = A.m_ints[0]; if (a0 == 1L) { return B; } /* * Fast path for small A, with performance dependent only on the number of set bits */ long[] c0 = new long[cLen]; MultiplyWord(a0, B.m_ints, bLen, c0, 0); /* * Reduce the raw answer against the reduction coefficients */ return ReduceResult(c0, 0, cLen, m, ks); } /* * Determine if B will get bigger during shifting */ int bMax = (int)((uint)(bDeg + 7 + 63) >> 6); /* * Lookup table for the offset of each B in the tables */ int[] ti = new int[16]; /* * Precompute table of all 4-bit products of B */ long[] T0 = new long[bMax << 4]; int tOff = bMax; ti[1] = tOff; Array.Copy(B.m_ints, 0, T0, tOff, bLen); for (int i = 2; i < 16; ++i) { ti[i] = (tOff += bMax); if ((i & 1) == 0) { ShiftUp(T0, (int)((uint)tOff >> 1), T0, tOff, bMax, 1); } else { Add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax); } } /* * Second table with all 4-bit products of B shifted 4 bits */ long[] T1 = new long[T0.Length]; ShiftUp(T0, 0, T1, 0, T0.Length, 4); // ShiftUp(T0, bMax, T1, bMax, tOff, 4); long[] a = A.m_ints; long[] c = new long[cLen << 3]; int MASK = 0xF; /* * Lopez-Dahab (Modified) algorithm */ for (int aPos = 0; aPos < aLen; ++aPos) { long aVal = a[aPos]; int cOff = aPos; for (;;) { int u = (int)aVal & MASK; aVal = (long)((ulong)aVal >> 4); int v = (int)aVal & MASK; AddBoth(c, cOff, T0, ti[u], T1, ti[v], bMax); aVal = (long)((ulong)aVal >> 4); if (aVal == 0L) { break; } cOff += cLen; } } { int cOff = c.Length; while ((cOff -= cLen) != 0) { AddShiftedUp(c, cOff - cLen, c, cOff, cLen, 8); } } /* * Finally the raw answer is collected, reduce it against the reduction coefficients */ return ReduceResult(c, 0, cLen, m, ks); }
public void AddShiftedByWords(LongArray other, int words) { int otherUsedLen = other.GetUsedLength(); if (otherUsedLen == 0) { return; } int minLen = otherUsedLen + words; if (minLen > m_ints.Length) { m_ints = ResizedInts(minLen); } Add(m_ints, words, other.m_ints, 0, otherUsedLen); }
// private void addShiftedByBits(LongArray other, int bits) // { // int words = bits >>> 6; // int shift = bits & 0x3F; // // if (shift == 0) // { // addShiftedByWords(other, words); // return; // } // // int otherUsedLen = other.GetUsedLength(); // if (otherUsedLen == 0) // { // return; // } // // int minLen = otherUsedLen + words + 1; // if (minLen > m_ints.Length) // { // m_ints = resizedInts(minLen); // } // // long carry = addShiftedByBits(m_ints, words, other.m_ints, 0, otherUsedLen, shift); // m_ints[otherUsedLen + words] ^= carry; // } private void AddShiftedByBitsSafe(LongArray other, int otherDegree, int bits) { int otherLen = (int)((uint)(otherDegree + 63) >> 6); int words = (int)((uint)bits >> 6); int shift = bits & 0x3F; if (shift == 0) { Add(m_ints, words, other.m_ints, 0, otherLen); return; } long carry = AddShiftedUp(m_ints, words, other.m_ints, 0, otherLen, shift); if (carry != 0L) { m_ints[otherLen + words] ^= carry; } }
public virtual bool Equals(LongArray other) { if (this == other) return true; if (null == other) return false; int usedLen = GetUsedLength(); if (other.GetUsedLength() != usedLen) { return false; } for (int i = 0; i < usedLen; i++) { if (m_ints[i] != other.m_ints[i]) { return false; } } return true; }
// private static LongArray ExpItohTsujii2(LongArray B, int n, int m, int[] ks) // { // LongArray t1 = B, t3 = new LongArray(new long[]{ 1L }); // int scale = 1; // // int numTerms = n; // while (numTerms > 1) // { // if ((numTerms & 1) != 0) // { // t3 = t3.ModMultiply(t1, m, ks); // t1 = t1.modSquareN(scale, m, ks); // } // // LongArray t2 = t1.modSquareN(scale, m, ks); // t1 = t1.ModMultiply(t2, m, ks); // numTerms >>>= 1; scale <<= 1; // } // // return t3.ModMultiply(t1, m, ks); // } // // private static LongArray ExpItohTsujii23(LongArray B, int n, int m, int[] ks) // { // LongArray t1 = B, t3 = new LongArray(new long[]{ 1L }); // int scale = 1; // // int numTerms = n; // while (numTerms > 1) // { // bool m03 = numTerms % 3 == 0; // bool m14 = !m03 && (numTerms & 1) != 0; // // if (m14) // { // t3 = t3.ModMultiply(t1, m, ks); // t1 = t1.modSquareN(scale, m, ks); // } // // LongArray t2 = t1.modSquareN(scale, m, ks); // t1 = t1.ModMultiply(t2, m, ks); // // if (m03) // { // t2 = t2.modSquareN(scale, m, ks); // t1 = t1.ModMultiply(t2, m, ks); // numTerms /= 3; scale *= 3; // } // else // { // numTerms >>>= 1; scale <<= 1; // } // } // // return t3.ModMultiply(t1, m, ks); // } // // private static LongArray ExpItohTsujii235(LongArray B, int n, int m, int[] ks) // { // LongArray t1 = B, t4 = new LongArray(new long[]{ 1L }); // int scale = 1; // // int numTerms = n; // while (numTerms > 1) // { // if (numTerms % 5 == 0) // { //// t1 = ExpItohTsujii23(t1, 5, m, ks); // // LongArray t3 = t1; // t1 = t1.modSquareN(scale, m, ks); // // LongArray t2 = t1.modSquareN(scale, m, ks); // t1 = t1.ModMultiply(t2, m, ks); // t2 = t1.modSquareN(scale << 1, m, ks); // t1 = t1.ModMultiply(t2, m, ks); // // t1 = t1.ModMultiply(t3, m, ks); // // numTerms /= 5; scale *= 5; // continue; // } // // bool m03 = numTerms % 3 == 0; // bool m14 = !m03 && (numTerms & 1) != 0; // // if (m14) // { // t4 = t4.ModMultiply(t1, m, ks); // t1 = t1.modSquareN(scale, m, ks); // } // // LongArray t2 = t1.modSquareN(scale, m, ks); // t1 = t1.ModMultiply(t2, m, ks); // // if (m03) // { // t2 = t2.modSquareN(scale, m, ks); // t1 = t1.ModMultiply(t2, m, ks); // numTerms /= 3; scale *= 3; // } // else // { // numTerms >>>= 1; scale <<= 1; // } // } // // return t4.ModMultiply(t1, m, ks); // } public LongArray ModInverse(int m, int[] ks) { /* * Fermat's Little Theorem */ // LongArray A = this; // LongArray B = A.modSquare(m, ks); // LongArray R0 = B, R1 = B; // for (int i = 2; i < m; ++i) // { // R1 = R1.modSquare(m, ks); // R0 = R0.ModMultiply(R1, m, ks); // } // // return R0; /* * Itoh-Tsujii */ // LongArray B = modSquare(m, ks); // switch (m) // { // case 409: // return ExpItohTsujii23(B, m - 1, m, ks); // case 571: // return ExpItohTsujii235(B, m - 1, m, ks); // case 163: // case 233: // case 283: // default: // return ExpItohTsujii2(B, m - 1, m, ks); // } /* * Inversion in F2m using the extended Euclidean algorithm * * Input: A nonzero polynomial a(z) of degree at most m-1 * Output: a(z)^(-1) mod f(z) */ int uzDegree = Degree(); if (uzDegree == 0) { throw new InvalidOperationException(); } if (uzDegree == 1) { return this; } // u(z) := a(z) LongArray uz = (LongArray)Copy(); int t = (m + 63) >> 6; // v(z) := f(z) LongArray vz = new LongArray(t); ReduceBit(vz.m_ints, 0, m, m, ks); // g1(z) := 1, g2(z) := 0 LongArray g1z = new LongArray(t); g1z.m_ints[0] = 1L; LongArray g2z = new LongArray(t); int[] uvDeg = new int[]{ uzDegree, m + 1 }; LongArray[] uv = new LongArray[]{ uz, vz }; int[] ggDeg = new int[]{ 1, 0 }; LongArray[] gg = new LongArray[]{ g1z, g2z }; int b = 1; int duv1 = uvDeg[b]; int dgg1 = ggDeg[b]; int j = duv1 - uvDeg[1 - b]; for (;;) { if (j < 0) { j = -j; uvDeg[b] = duv1; ggDeg[b] = dgg1; b = 1 - b; duv1 = uvDeg[b]; dgg1 = ggDeg[b]; } uv[b].AddShiftedByBitsSafe(uv[1 - b], uvDeg[1 - b], j); int duv2 = uv[b].DegreeFrom(duv1); if (duv2 == 0) { return gg[1 - b]; } { int dgg2 = ggDeg[1 - b]; gg[b].AddShiftedByBitsSafe(gg[1 - b], dgg2, j); dgg2 += j; if (dgg2 > dgg1) { dgg1 = dgg2; } else if (dgg2 == dgg1) { dgg1 = gg[b].DegreeFrom(dgg1); } } j += (duv2 - duv1); duv1 = duv2; } }
public LongArray ModMultiplyAlt(LongArray other, int m, int[] ks) { /* * Find out the degree of each argument and handle the zero cases */ int aDeg = Degree(); if (aDeg == 0) { return this; } int bDeg = other.Degree(); if (bDeg == 0) { return other; } /* * Swap if necessary so that A is the smaller argument */ LongArray A = this, B = other; if (aDeg > bDeg) { A = other; B = this; int tmp = aDeg; aDeg = bDeg; bDeg = tmp; } /* * Establish the word lengths of the arguments and result */ int aLen = (int)((uint)(aDeg + 63) >> 6); int bLen = (int)((uint)(bDeg + 63) >> 6); int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6); if (aLen == 1) { long a0 = A.m_ints[0]; if (a0 == 1L) { return B; } /* * Fast path for small A, with performance dependent only on the number of set bits */ long[] c0 = new long[cLen]; MultiplyWord(a0, B.m_ints, bLen, c0, 0); /* * Reduce the raw answer against the reduction coefficients */ return ReduceResult(c0, 0, cLen, m, ks); } // NOTE: This works, but is slower than width 4 processing // if (aLen == 2) // { // /* // * Use common-multiplicand optimization to save ~1/4 of the adds // */ // long a1 = A.m_ints[0], a2 = A.m_ints[1]; // long aa = a1 & a2; a1 ^= aa; a2 ^= aa; // // long[] b = B.m_ints; // long[] c = new long[cLen]; // multiplyWord(aa, b, bLen, c, 1); // add(c, 0, c, 1, cLen - 1); // multiplyWord(a1, b, bLen, c, 0); // multiplyWord(a2, b, bLen, c, 1); // // /* // * Reduce the raw answer against the reduction coefficients // */ // return ReduceResult(c, 0, cLen, m, ks); // } /* * Determine the parameters of the Interleaved window algorithm: the 'width' in bits to * process together, the number of evaluation 'positions' implied by that width, and the * 'top' position at which the regular window algorithm stops. */ int width, positions, top, banks; // NOTE: width 4 is the fastest over the entire range of sizes used in current crypto // width = 1; positions = 64; top = 64; banks = 4; // width = 2; positions = 32; top = 64; banks = 4; // width = 3; positions = 21; top = 63; banks = 3; width = 4; positions = 16; top = 64; banks = 8; // width = 5; positions = 13; top = 65; banks = 7; // width = 7; positions = 9; top = 63; banks = 9; // width = 8; positions = 8; top = 64; banks = 8; /* * Determine if B will get bigger during shifting */ int shifts = top < 64 ? positions : positions - 1; int bMax = (int)((uint)(bDeg + shifts + 63) >> 6); int bTotal = bMax * banks, stride = width * banks; /* * Create a single temporary buffer, with an offset table to find the positions of things in it */ int[] ci = new int[1 << width]; int cTotal = aLen; { ci[0] = cTotal; cTotal += bTotal; ci[1] = cTotal; for (int i = 2; i < ci.Length; ++i) { cTotal += cLen; ci[i] = cTotal; } cTotal += cLen; } // NOTE: Provide a safe dump for "high zeroes" since we are adding 'bMax' and not 'bLen' ++cTotal; long[] c = new long[cTotal]; // Prepare A in Interleaved form, according to the chosen width Interleave(A.m_ints, 0, c, 0, aLen, width); // Make a working copy of B, since we will be shifting it { int bOff = aLen; Array.Copy(B.m_ints, 0, c, bOff, bLen); for (int bank = 1; bank < banks; ++bank) { ShiftUp(c, aLen, c, bOff += bMax, bMax, bank); } } /* * The main loop analyzes the Interleaved windows in A, and for each non-zero window * a single word-array XOR is performed to a carefully selected slice of 'c'. The loop is * breadth-first, checking the lowest window in each word, then looping again for the * next higher window position. */ int MASK = (1 << width) - 1; int k = 0; for (;;) { int aPos = 0; do { long aVal = (long)((ulong)c[aPos] >> k); int bank = 0, bOff = aLen; for (;;) { int index = (int)(aVal) & MASK; if (index != 0) { /* * Add to a 'c' buffer based on the bit-pattern of 'index'. Since A is in * Interleaved form, the bits represent the current B shifted by 0, 'positions', * 'positions' * 2, ..., 'positions' * ('width' - 1) */ Add(c, aPos + ci[index], c, bOff, bMax); } if (++bank == banks) { break; } bOff += bMax; aVal = (long)((ulong)aVal >> width); } } while (++aPos < aLen); if ((k += stride) >= top) { if (k >= 64) { break; } /* * Adjustment for window setups with top == 63, the final bit (if any) is processed * as the top-bit of a window */ k = 64 - width; MASK &= MASK << (top - k); } /* * After each position has been checked for all words of A, B is shifted up 1 place */ ShiftUp(c, aLen, bTotal, banks); } int ciPos = ci.Length; while (--ciPos > 1) { if ((ciPos & 1L) == 0L) { /* * For even numbers, shift contents and add to the half-position */ AddShiftedUp(c, ci[(uint)ciPos >> 1], c, ci[ciPos], cLen, positions); } else { /* * For odd numbers, 'distribute' contents to the result and the next-lowest position */ Distribute(c, ci[ciPos], ci[ciPos - 1], ci[1], cLen); } } /* * Finally the raw answer is collected, reduce it against the reduction coefficients */ return ReduceResult(c, ci[1], cLen, m, ks); }
public LongArray ModInverse(int m, int[] ks) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) int num = Degree(); switch (num) { case 0: throw new InvalidOperationException(); case 1: return(this); default: { LongArray longArray = Copy(); int intLen = m + 63 >> 6; LongArray longArray2 = new LongArray(intLen); ReduceBit(longArray2.m_ints, 0, m, m, ks); LongArray longArray3 = new LongArray(intLen); longArray3.m_ints[0] = 1L; LongArray longArray4 = new LongArray(intLen); int[] array = new int[2] { num, m + 1 }; LongArray[] array2 = new LongArray[2] { longArray, longArray2 }; int[] array3 = new int[2] { 1, 0 }; LongArray[] array4 = new LongArray[2] { longArray3, longArray4 }; int num2 = 1; int num3 = array[num2]; int num4 = array3[num2]; int num5 = num3 - array[1 - num2]; while (true) { if (num5 < 0) { num5 = -num5; array[num2] = num3; array3[num2] = num4; num2 = 1 - num2; num3 = array[num2]; num4 = array3[num2]; } array2[num2].AddShiftedByBitsSafe(array2[1 - num2], array[1 - num2], num5); int num6 = array2[num2].DegreeFrom(num3); if (num6 == 0) { break; } int num7 = array3[1 - num2]; array4[num2].AddShiftedByBitsSafe(array4[1 - num2], num7, num5); num7 += num5; if (num7 > num4) { num4 = num7; } else if (num7 == num4) { num4 = array4[num2].DegreeFrom(num4); } num5 += num6 - num3; num3 = num6; } return(array4[1 - num2]); } } }
public LongArray Multiply(LongArray other, int m, int[] ks) { int num = Degree(); if (num == 0) { return(this); } int num2 = other.Degree(); if (num2 == 0) { return(other); } LongArray longArray = this; LongArray longArray2 = other; if (num > num2) { longArray = other; longArray2 = this; int num3 = num; num = num2; num2 = num3; } int num4 = (int)((uint)(num + 63) >> 6); int num5 = (int)((uint)(num2 + 63) >> 6); int num6 = (int)((uint)(num + num2 + 62) >> 6); if (num4 == 1) { long num7 = longArray.m_ints[0]; if (num7 == 1) { return(longArray2); } long[] array = new long[num6]; MultiplyWord(num7, longArray2.m_ints, num5, array, 0); return(new LongArray(array, 0, num6)); } int num8 = (int)((uint)(num2 + 7 + 63) >> 6); int[] array2 = new int[16]; long[] array3 = new long[num8 << 4]; int num9 = (array2[1] = num8); global::System.Array.Copy((global::System.Array)longArray2.m_ints, 0, (global::System.Array)array3, num9, num5); for (int i = 2; i < 16; i++) { num9 = (array2[i] = num9 + num8); if ((i & 1) == 0) { ShiftUp(array3, (int)((uint)num9 >> 1), array3, num9, num8, 1); } else { Add(array3, num8, array3, num9 - num8, array3, num9, num8); } } long[] array4 = new long[array3.Length]; ShiftUp(array3, 0, array4, 0, array3.Length, 4); long[] ints = longArray.m_ints; long[] array5 = new long[num6 << 3]; int num10 = 15; for (int j = 0; j < num4; j++) { long num11 = ints[j]; int num12 = j; while (true) { int num13 = (int)num11 & num10; num11 = (long)((ulong)num11 >> 4); int num14 = (int)num11 & num10; AddBoth(array5, num12, array3, array2[num13], array4, array2[num14], num8); num11 = (long)((ulong)num11 >> 4); if (num11 == 0) { break; } num12 += num6; } } int num15 = array5.Length; while ((num15 -= num6) != 0) { AddShiftedUp(array5, num15 - num6, array5, num15, num6, 8); } return(new LongArray(array5, 0, num6)); }
public LongArray ModMultiplyAlt(LongArray other, int m, int[] ks) { int num = Degree(); if (num == 0) { return(this); } int num2 = other.Degree(); if (num2 == 0) { return(other); } LongArray longArray = this; LongArray longArray2 = other; if (num > num2) { longArray = other; longArray2 = this; int num3 = num; num = num2; num2 = num3; } int num4 = (int)((uint)(num + 63) >> 6); int num5 = (int)((uint)(num2 + 63) >> 6); int num6 = (int)((uint)(num + num2 + 62) >> 6); if (num4 == 1) { long num7 = longArray.m_ints[0]; if (num7 == 1) { return(longArray2); } long[] array = new long[num6]; MultiplyWord(num7, longArray2.m_ints, num5, array, 0); return(ReduceResult(array, 0, num6, m, ks)); } int num8 = 4; int num9 = 16; int num10 = 64; int num11 = 8; int num12 = ((num10 < 64) ? num9 : (num9 - 1)); int num13 = (int)((uint)(num2 + num12 + 63) >> 6); int num14 = num13 * num11; int num15 = num8 * num11; int[] array2 = new int[1 << num8]; int num16 = (array2[1] = (array2[0] = num4) + num14); for (int i = 2; i < array2.Length; i++) { num16 = (array2[i] = num16 + num6); } num16 += num6; num16++; long[] array3 = new long[num16]; Interleave(longArray.m_ints, 0, array3, 0, num4, num8); int num17 = num4; global::System.Array.Copy((global::System.Array)longArray2.m_ints, 0, (global::System.Array)array3, num17, num5); for (int j = 1; j < num11; j++) { ShiftUp(array3, num4, array3, num17 += num13, num13, j); } int num18 = (1 << num8) - 1; int num19 = 0; while (true) { int num20 = 0; do { long num21 = (long)((ulong)array3[num20] >> num19); int num22 = 0; int num23 = num4; while (true) { int num24 = (int)num21 & num18; if (num24 != 0) { Add(array3, num20 + array2[num24], array3, num23, num13); } if (++num22 == num11) { break; } num23 += num13; num21 = (long)((ulong)num21 >> num8); } }while (++num20 < num4); if ((num19 += num15) >= num10) { if (num19 >= 64) { break; } num19 = 64 - num8; num18 &= num18 << num10 - num19; } ShiftUp(array3, num4, num14, num11); } int num25 = array2.Length; while (--num25 > 1) { if (((ulong)num25 & 1uL) == 0) { AddShiftedUp(array3, array2[(uint)num25 >> 1], array3, array2[num25], num6, num9); } else { Distribute(array3, array2[num25], array2[num25 - 1], array2[1], num6); } } return(ReduceResult(array3, array2[1], num6, m, ks)); }
public LongArray ModMultiplyLD(LongArray other, int m, int[] ks) { int num = Degree(); if (num == 0) { return(this); } int num2 = other.Degree(); if (num2 == 0) { return(other); } LongArray longArray = this; LongArray longArray2 = other; if (num > num2) { longArray = other; longArray2 = this; int num3 = num; num = num2; num2 = num3; } int num4 = (int)((uint)(num + 63) >> 6); int num5 = (int)((uint)(num2 + 63) >> 6); int num6 = (int)((uint)(num + num2 + 62) >> 6); if (num4 == 1) { long num7 = longArray.m_ints[0]; if (num7 == 1) { return(longArray2); } long[] array = new long[num6]; MultiplyWord(num7, longArray2.m_ints, num5, array, 0); return(ReduceResult(array, 0, num6, m, ks)); } int num8 = (int)((uint)(num2 + 7 + 63) >> 6); int[] array2 = new int[16]; long[] array3 = new long[num8 << 4]; int num9 = (array2[1] = num8); global::System.Array.Copy((global::System.Array)longArray2.m_ints, 0, (global::System.Array)array3, num9, num5); for (int i = 2; i < 16; i++) { num9 = (array2[i] = num9 + num8); if ((i & 1) == 0) { ShiftUp(array3, (int)((uint)num9 >> 1), array3, num9, num8, 1); } else { Add(array3, num8, array3, num9 - num8, array3, num9, num8); } } long[] array4 = new long[array3.Length]; ShiftUp(array3, 0, array4, 0, array3.Length, 4); long[] ints = longArray.m_ints; long[] array5 = new long[num6]; int num10 = 15; for (int num11 = 56; num11 >= 0; num11 -= 8) { for (int j = 1; j < num4; j += 2) { int num12 = (int)((ulong)ints[j] >> num11); int num13 = num12 & num10; int num14 = (int)((uint)num12 >> 4) & num10; AddBoth(array5, j - 1, array3, array2[num13], array4, array2[num14], num8); } ShiftUp(array5, 0, num6, 8); } for (int num15 = 56; num15 >= 0; num15 -= 8) { for (int k = 0; k < num4; k += 2) { int num16 = (int)((ulong)ints[k] >> num15); int num17 = num16 & num10; int num18 = (int)((uint)num16 >> 4) & num10; AddBoth(array5, k, array3, array2[num17], array4, array2[num18], num8); } if (num15 > 0) { ShiftUp(array5, 0, num6, 8); } } return(ReduceResult(array5, 0, num6, m, ks)); }
/** * Constructor for Ppb. * @param m The exponent <code>m</code> of * <code>F<sub>2<sup>m</sup></sub></code>. * @param k1 The integer <code>k1</code> where <code>x<sup>m</sup> + * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> * represents the reduction polynomial <code>f(z)</code>. * @param k2 The integer <code>k2</code> where <code>x<sup>m</sup> + * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> * represents the reduction polynomial <code>f(z)</code>. * @param k3 The integer <code>k3</code> where <code>x<sup>m</sup> + * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> * represents the reduction polynomial <code>f(z)</code>. * @param x The BigInteger representing the value of the field element. */ public F2mFieldElement( int m, int k1, int k2, int k3, BigInteger x) { if ((k2 == 0) && (k3 == 0)) { this.representation = Tpb; this.ks = new int[] { k1 }; } else { if (k2 >= k3) throw new ArgumentException("k2 must be smaller than k3"); if (k2 <= 0) throw new ArgumentException("k2 must be larger than 0"); this.representation = Ppb; this.ks = new int[] { k1, k2, k3 }; } this.m = m; this.x = new LongArray(x); }
private F2mFieldElement(int m, int[] ks, LongArray x) { this.m = m; this.representation = (ks.Length == 1) ? Tpb : Ppb; this.ks = ks; this.x = x; }
/** * Constructor for Ppb. * @param m The exponent <code>m</code> of * <code>F<sub>2<sup>m</sup></sub></code>. * @param k1 The integer <code>k1</code> where <code>x<sup>m</sup> + * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> * represents the reduction polynomial <code>f(z)</code>. * @param k2 The integer <code>k2</code> where <code>x<sup>m</sup> + * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> * represents the reduction polynomial <code>f(z)</code>. * @param k3 The integer <code>k3</code> where <code>x<sup>m</sup> + * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> * represents the reduction polynomial <code>f(z)</code>. * @param x The BigInteger representing the value of the field element. */ public F2mFieldElement( int m, int k1, int k2, int k3, BigInteger x) { if (x == null || x.SignValue < 0 || x.BitLength > m) throw new ArgumentException("value invalid in F2m field element", "x"); if ((k2 == 0) && (k3 == 0)) { this.representation = Tpb; this.ks = new int[] { k1 }; } else { if (k2 >= k3) throw new ArgumentException("k2 must be smaller than k3"); if (k2 <= 0) throw new ArgumentException("k2 must be larger than 0"); this.representation = Ppb; this.ks = new int[] { k1, k2, k3 }; } this.m = m; this.x = new LongArray(x); }