Example #1
0
        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));
        }
Example #2
0
        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));
        }
Example #4
0
        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));
        }
Example #5
0
        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;
            }
        }
Example #6
0
        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);
        }
Example #7
0
        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);
        }
Example #8
0
    //    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;
            }
        }
Example #9
0
 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;
 }
Example #10
0
    //    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;
            }
        }
Example #11
0
        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);
        }
Example #12
0
        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]);
            }
            }
        }
Example #13
0
        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));
        }
Example #14
0
        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));
        }
Example #15
0
        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));
        }
Example #16
0
        /**
            * 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);
        }
Example #17
0
 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);
        }