< Summary

Information
Class: Renci.SshNet.Security.Org.BouncyCastle.Math.EC.LongArray
Assembly: Renci.SshNet
File(s): \home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\BouncyCastle\math\ec\LongArray.cs
Line coverage
19%
Covered lines: 257
Uncovered lines: 1061
Coverable lines: 1318
Total lines: 2206
Line coverage: 19.4%
Branch coverage
0%
Covered branches: 0
Total branches: 300
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.cctor()100%1100%
.ctor(...)100%10%
.ctor(...)100%10%
.ctor(...)0%40%
.ctor(...)0%160%
CopyTo(...)100%10%
IsOne()0%60%
IsZero()0%40%
GetUsedLength()100%10%
GetUsedLengthFrom(...)0%100%
Degree()0%40%
DegreeFrom(...)0%40%
BitLength(...)0%80%
ResizedInts(...)100%10%
ToBigInteger()0%140%
ShiftUp(...)0%20%
ShiftUp(...)0%20%
AddOne()0%20%
AddShiftedByBitsSafe(...)0%40%
AddShiftedUp(...)0%20%
AddShiftedDown(...)0%20%
AddShiftedByWords(...)0%40%
Add(...)0%20%
Add(...)0%20%
AddBoth(...)0%20%
Distribute(...)0%20%
get_Length()100%10%
FlipWord(...)0%40%
TestBitZero()0%20%
TestBit(...)100%10%
FlipBit(...)100%10%
MultiplyWord(...)0%80%
ModMultiplyLD(...)0%240%
ModMultiply(...)0%200%
ModMultiplyAlt(...)0%300%
ModReduce(...)100%10%
Multiply(...)0%200%
Reduce(...)0%20%
ReduceResult(...)100%10%
ReduceInPlace(...)0%140%
ReduceBitWise(...)0%40%
ReduceBit(...)0%20%
ReduceWordWise(...)0%60%
ReduceWord(...)0%20%
ReduceVectorWise(...)0%20%
FlipVector(...)0%20%
ModSquare(...)0%40%
ModSquareN(...)0%40%
Square(...)0%40%
SquareInPlace(...)0%20%
Interleave(...)0%60%
Interleave3(...)0%20%
Interleave3(...)100%10%
Interleave3_21to63(...)100%10%
Interleave5(...)0%20%
Interleave5(...)100%10%
Interleave3_13to65(...)100%10%
Interleave7(...)0%20%
Interleave7(...)100%10%
Interleave2_n(...)0%20%
Interleave2_n(...)0%40%
Interleave4_16to64(...)100%10%
Interleave2_32to64(...)100%10%
ModInverse(...)0%120%
Equals(...)100%10%
Equals(...)0%100%
GetHashCode()0%20%
Copy()100%10%
ToString()0%60%

File(s)

\home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\BouncyCastle\math\ec\LongArray.cs

#LineLine coverage
 1using System;
 2using System.Text;
 3
 4using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
 5
 6namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC
 7{
 8    internal class LongArray
 9    {
 10        //private static long DEInterleave_MASK = 0x5555555555555555L;
 11
 12        /*
 13         * This expands 8 bit indices into 16 bit contents (high bit 14), by inserting 0s between bits.
 14         * In a binary field, this operation is the same as squaring an 8 bit number.
 15         */
 116        private static readonly ushort[] INTERLEAVE2_TABLE = new ushort[]
 117        {
 118            0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015,
 119            0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055,
 120            0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115,
 121            0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155,
 122            0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415,
 123            0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455,
 124            0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515,
 125            0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555,
 126            0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015,
 127            0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055,
 128            0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115,
 129            0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155,
 130            0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415,
 131            0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455,
 132            0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515,
 133            0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555,
 134            0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015,
 135            0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055,
 136            0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115,
 137            0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155,
 138            0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415,
 139            0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455,
 140            0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515,
 141            0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555,
 142            0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015,
 143            0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055,
 144            0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115,
 145            0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155,
 146            0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415,
 147            0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455,
 148            0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515,
 149            0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555
 150        };
 51
 52        /*
 53         * This expands 7 bit indices into 21 bit contents (high bit 18), by inserting 0s between bits.
 54         */
 155        private static readonly int[] INTERLEAVE3_TABLE = new  int[]
 156        {
 157            0x00000, 0x00001, 0x00008, 0x00009, 0x00040, 0x00041, 0x00048, 0x00049,
 158            0x00200, 0x00201, 0x00208, 0x00209, 0x00240, 0x00241, 0x00248, 0x00249,
 159            0x01000, 0x01001, 0x01008, 0x01009, 0x01040, 0x01041, 0x01048, 0x01049,
 160            0x01200, 0x01201, 0x01208, 0x01209, 0x01240, 0x01241, 0x01248, 0x01249,
 161            0x08000, 0x08001, 0x08008, 0x08009, 0x08040, 0x08041, 0x08048, 0x08049,
 162            0x08200, 0x08201, 0x08208, 0x08209, 0x08240, 0x08241, 0x08248, 0x08249,
 163            0x09000, 0x09001, 0x09008, 0x09009, 0x09040, 0x09041, 0x09048, 0x09049,
 164            0x09200, 0x09201, 0x09208, 0x09209, 0x09240, 0x09241, 0x09248, 0x09249,
 165            0x40000, 0x40001, 0x40008, 0x40009, 0x40040, 0x40041, 0x40048, 0x40049,
 166            0x40200, 0x40201, 0x40208, 0x40209, 0x40240, 0x40241, 0x40248, 0x40249,
 167            0x41000, 0x41001, 0x41008, 0x41009, 0x41040, 0x41041, 0x41048, 0x41049,
 168            0x41200, 0x41201, 0x41208, 0x41209, 0x41240, 0x41241, 0x41248, 0x41249,
 169            0x48000, 0x48001, 0x48008, 0x48009, 0x48040, 0x48041, 0x48048, 0x48049,
 170            0x48200, 0x48201, 0x48208, 0x48209, 0x48240, 0x48241, 0x48248, 0x48249,
 171            0x49000, 0x49001, 0x49008, 0x49009, 0x49040, 0x49041, 0x49048, 0x49049,
 172            0x49200, 0x49201, 0x49208, 0x49209, 0x49240, 0x49241, 0x49248, 0x49249
 173        };
 74
 75        /*
 76         * This expands 8 bit indices into 32 bit contents (high bit 28), by inserting 0s between bits.
 77         */
 178        private static readonly int[] INTERLEAVE4_TABLE = new int[]
 179        {
 180            0x00000000, 0x00000001, 0x00000010, 0x00000011, 0x00000100, 0x00000101, 0x00000110, 0x00000111,
 181            0x00001000, 0x00001001, 0x00001010, 0x00001011, 0x00001100, 0x00001101, 0x00001110, 0x00001111,
 182            0x00010000, 0x00010001, 0x00010010, 0x00010011, 0x00010100, 0x00010101, 0x00010110, 0x00010111,
 183            0x00011000, 0x00011001, 0x00011010, 0x00011011, 0x00011100, 0x00011101, 0x00011110, 0x00011111,
 184            0x00100000, 0x00100001, 0x00100010, 0x00100011, 0x00100100, 0x00100101, 0x00100110, 0x00100111,
 185            0x00101000, 0x00101001, 0x00101010, 0x00101011, 0x00101100, 0x00101101, 0x00101110, 0x00101111,
 186            0x00110000, 0x00110001, 0x00110010, 0x00110011, 0x00110100, 0x00110101, 0x00110110, 0x00110111,
 187            0x00111000, 0x00111001, 0x00111010, 0x00111011, 0x00111100, 0x00111101, 0x00111110, 0x00111111,
 188            0x01000000, 0x01000001, 0x01000010, 0x01000011, 0x01000100, 0x01000101, 0x01000110, 0x01000111,
 189            0x01001000, 0x01001001, 0x01001010, 0x01001011, 0x01001100, 0x01001101, 0x01001110, 0x01001111,
 190            0x01010000, 0x01010001, 0x01010010, 0x01010011, 0x01010100, 0x01010101, 0x01010110, 0x01010111,
 191            0x01011000, 0x01011001, 0x01011010, 0x01011011, 0x01011100, 0x01011101, 0x01011110, 0x01011111,
 192            0x01100000, 0x01100001, 0x01100010, 0x01100011, 0x01100100, 0x01100101, 0x01100110, 0x01100111,
 193            0x01101000, 0x01101001, 0x01101010, 0x01101011, 0x01101100, 0x01101101, 0x01101110, 0x01101111,
 194            0x01110000, 0x01110001, 0x01110010, 0x01110011, 0x01110100, 0x01110101, 0x01110110, 0x01110111,
 195            0x01111000, 0x01111001, 0x01111010, 0x01111011, 0x01111100, 0x01111101, 0x01111110, 0x01111111,
 196            0x10000000, 0x10000001, 0x10000010, 0x10000011, 0x10000100, 0x10000101, 0x10000110, 0x10000111,
 197            0x10001000, 0x10001001, 0x10001010, 0x10001011, 0x10001100, 0x10001101, 0x10001110, 0x10001111,
 198            0x10010000, 0x10010001, 0x10010010, 0x10010011, 0x10010100, 0x10010101, 0x10010110, 0x10010111,
 199            0x10011000, 0x10011001, 0x10011010, 0x10011011, 0x10011100, 0x10011101, 0x10011110, 0x10011111,
 1100            0x10100000, 0x10100001, 0x10100010, 0x10100011, 0x10100100, 0x10100101, 0x10100110, 0x10100111,
 1101            0x10101000, 0x10101001, 0x10101010, 0x10101011, 0x10101100, 0x10101101, 0x10101110, 0x10101111,
 1102            0x10110000, 0x10110001, 0x10110010, 0x10110011, 0x10110100, 0x10110101, 0x10110110, 0x10110111,
 1103            0x10111000, 0x10111001, 0x10111010, 0x10111011, 0x10111100, 0x10111101, 0x10111110, 0x10111111,
 1104            0x11000000, 0x11000001, 0x11000010, 0x11000011, 0x11000100, 0x11000101, 0x11000110, 0x11000111,
 1105            0x11001000, 0x11001001, 0x11001010, 0x11001011, 0x11001100, 0x11001101, 0x11001110, 0x11001111,
 1106            0x11010000, 0x11010001, 0x11010010, 0x11010011, 0x11010100, 0x11010101, 0x11010110, 0x11010111,
 1107            0x11011000, 0x11011001, 0x11011010, 0x11011011, 0x11011100, 0x11011101, 0x11011110, 0x11011111,
 1108            0x11100000, 0x11100001, 0x11100010, 0x11100011, 0x11100100, 0x11100101, 0x11100110, 0x11100111,
 1109            0x11101000, 0x11101001, 0x11101010, 0x11101011, 0x11101100, 0x11101101, 0x11101110, 0x11101111,
 1110            0x11110000, 0x11110001, 0x11110010, 0x11110011, 0x11110100, 0x11110101, 0x11110110, 0x11110111,
 1111            0x11111000, 0x11111001, 0x11111010, 0x11111011, 0x11111100, 0x11111101, 0x11111110, 0x11111111
 1112        };
 113
 114        /*
 115         * This expands 7 bit indices into 35 bit contents (high bit 30), by inserting 0s between bits.
 116         */
 1117        private static readonly int[] INTERLEAVE5_TABLE = new int[] {
 1118            0x00000000, 0x00000001, 0x00000020, 0x00000021, 0x00000400, 0x00000401, 0x00000420, 0x00000421,
 1119            0x00008000, 0x00008001, 0x00008020, 0x00008021, 0x00008400, 0x00008401, 0x00008420, 0x00008421,
 1120            0x00100000, 0x00100001, 0x00100020, 0x00100021, 0x00100400, 0x00100401, 0x00100420, 0x00100421,
 1121            0x00108000, 0x00108001, 0x00108020, 0x00108021, 0x00108400, 0x00108401, 0x00108420, 0x00108421,
 1122            0x02000000, 0x02000001, 0x02000020, 0x02000021, 0x02000400, 0x02000401, 0x02000420, 0x02000421,
 1123            0x02008000, 0x02008001, 0x02008020, 0x02008021, 0x02008400, 0x02008401, 0x02008420, 0x02008421,
 1124            0x02100000, 0x02100001, 0x02100020, 0x02100021, 0x02100400, 0x02100401, 0x02100420, 0x02100421,
 1125            0x02108000, 0x02108001, 0x02108020, 0x02108021, 0x02108400, 0x02108401, 0x02108420, 0x02108421,
 1126            0x40000000, 0x40000001, 0x40000020, 0x40000021, 0x40000400, 0x40000401, 0x40000420, 0x40000421,
 1127            0x40008000, 0x40008001, 0x40008020, 0x40008021, 0x40008400, 0x40008401, 0x40008420, 0x40008421,
 1128            0x40100000, 0x40100001, 0x40100020, 0x40100021, 0x40100400, 0x40100401, 0x40100420, 0x40100421,
 1129            0x40108000, 0x40108001, 0x40108020, 0x40108021, 0x40108400, 0x40108401, 0x40108420, 0x40108421,
 1130            0x42000000, 0x42000001, 0x42000020, 0x42000021, 0x42000400, 0x42000401, 0x42000420, 0x42000421,
 1131            0x42008000, 0x42008001, 0x42008020, 0x42008021, 0x42008400, 0x42008401, 0x42008420, 0x42008421,
 1132            0x42100000, 0x42100001, 0x42100020, 0x42100021, 0x42100400, 0x42100401, 0x42100420, 0x42100421,
 1133            0x42108000, 0x42108001, 0x42108020, 0x42108021, 0x42108400, 0x42108401, 0x42108420, 0x42108421
 1134        };
 135
 136        /*
 137         * This expands 9 bit indices into 63 bit (long) contents (high bit 56), by inserting 0s between bits.
 138         */
 1139        private static readonly long[] INTERLEAVE7_TABLE = new long[]
 1140        {
 1141            0x0000000000000000L, 0x0000000000000001L, 0x0000000000000080L, 0x0000000000000081L,
 1142            0x0000000000004000L, 0x0000000000004001L, 0x0000000000004080L, 0x0000000000004081L,
 1143            0x0000000000200000L, 0x0000000000200001L, 0x0000000000200080L, 0x0000000000200081L,
 1144            0x0000000000204000L, 0x0000000000204001L, 0x0000000000204080L, 0x0000000000204081L,
 1145            0x0000000010000000L, 0x0000000010000001L, 0x0000000010000080L, 0x0000000010000081L,
 1146            0x0000000010004000L, 0x0000000010004001L, 0x0000000010004080L, 0x0000000010004081L,
 1147            0x0000000010200000L, 0x0000000010200001L, 0x0000000010200080L, 0x0000000010200081L,
 1148            0x0000000010204000L, 0x0000000010204001L, 0x0000000010204080L, 0x0000000010204081L,
 1149            0x0000000800000000L, 0x0000000800000001L, 0x0000000800000080L, 0x0000000800000081L,
 1150            0x0000000800004000L, 0x0000000800004001L, 0x0000000800004080L, 0x0000000800004081L,
 1151            0x0000000800200000L, 0x0000000800200001L, 0x0000000800200080L, 0x0000000800200081L,
 1152            0x0000000800204000L, 0x0000000800204001L, 0x0000000800204080L, 0x0000000800204081L,
 1153            0x0000000810000000L, 0x0000000810000001L, 0x0000000810000080L, 0x0000000810000081L,
 1154            0x0000000810004000L, 0x0000000810004001L, 0x0000000810004080L, 0x0000000810004081L,
 1155            0x0000000810200000L, 0x0000000810200001L, 0x0000000810200080L, 0x0000000810200081L,
 1156            0x0000000810204000L, 0x0000000810204001L, 0x0000000810204080L, 0x0000000810204081L,
 1157            0x0000040000000000L, 0x0000040000000001L, 0x0000040000000080L, 0x0000040000000081L,
 1158            0x0000040000004000L, 0x0000040000004001L, 0x0000040000004080L, 0x0000040000004081L,
 1159            0x0000040000200000L, 0x0000040000200001L, 0x0000040000200080L, 0x0000040000200081L,
 1160            0x0000040000204000L, 0x0000040000204001L, 0x0000040000204080L, 0x0000040000204081L,
 1161            0x0000040010000000L, 0x0000040010000001L, 0x0000040010000080L, 0x0000040010000081L,
 1162            0x0000040010004000L, 0x0000040010004001L, 0x0000040010004080L, 0x0000040010004081L,
 1163            0x0000040010200000L, 0x0000040010200001L, 0x0000040010200080L, 0x0000040010200081L,
 1164            0x0000040010204000L, 0x0000040010204001L, 0x0000040010204080L, 0x0000040010204081L,
 1165            0x0000040800000000L, 0x0000040800000001L, 0x0000040800000080L, 0x0000040800000081L,
 1166            0x0000040800004000L, 0x0000040800004001L, 0x0000040800004080L, 0x0000040800004081L,
 1167            0x0000040800200000L, 0x0000040800200001L, 0x0000040800200080L, 0x0000040800200081L,
 1168            0x0000040800204000L, 0x0000040800204001L, 0x0000040800204080L, 0x0000040800204081L,
 1169            0x0000040810000000L, 0x0000040810000001L, 0x0000040810000080L, 0x0000040810000081L,
 1170            0x0000040810004000L, 0x0000040810004001L, 0x0000040810004080L, 0x0000040810004081L,
 1171            0x0000040810200000L, 0x0000040810200001L, 0x0000040810200080L, 0x0000040810200081L,
 1172            0x0000040810204000L, 0x0000040810204001L, 0x0000040810204080L, 0x0000040810204081L,
 1173            0x0002000000000000L, 0x0002000000000001L, 0x0002000000000080L, 0x0002000000000081L,
 1174            0x0002000000004000L, 0x0002000000004001L, 0x0002000000004080L, 0x0002000000004081L,
 1175            0x0002000000200000L, 0x0002000000200001L, 0x0002000000200080L, 0x0002000000200081L,
 1176            0x0002000000204000L, 0x0002000000204001L, 0x0002000000204080L, 0x0002000000204081L,
 1177            0x0002000010000000L, 0x0002000010000001L, 0x0002000010000080L, 0x0002000010000081L,
 1178            0x0002000010004000L, 0x0002000010004001L, 0x0002000010004080L, 0x0002000010004081L,
 1179            0x0002000010200000L, 0x0002000010200001L, 0x0002000010200080L, 0x0002000010200081L,
 1180            0x0002000010204000L, 0x0002000010204001L, 0x0002000010204080L, 0x0002000010204081L,
 1181            0x0002000800000000L, 0x0002000800000001L, 0x0002000800000080L, 0x0002000800000081L,
 1182            0x0002000800004000L, 0x0002000800004001L, 0x0002000800004080L, 0x0002000800004081L,
 1183            0x0002000800200000L, 0x0002000800200001L, 0x0002000800200080L, 0x0002000800200081L,
 1184            0x0002000800204000L, 0x0002000800204001L, 0x0002000800204080L, 0x0002000800204081L,
 1185            0x0002000810000000L, 0x0002000810000001L, 0x0002000810000080L, 0x0002000810000081L,
 1186            0x0002000810004000L, 0x0002000810004001L, 0x0002000810004080L, 0x0002000810004081L,
 1187            0x0002000810200000L, 0x0002000810200001L, 0x0002000810200080L, 0x0002000810200081L,
 1188            0x0002000810204000L, 0x0002000810204001L, 0x0002000810204080L, 0x0002000810204081L,
 1189            0x0002040000000000L, 0x0002040000000001L, 0x0002040000000080L, 0x0002040000000081L,
 1190            0x0002040000004000L, 0x0002040000004001L, 0x0002040000004080L, 0x0002040000004081L,
 1191            0x0002040000200000L, 0x0002040000200001L, 0x0002040000200080L, 0x0002040000200081L,
 1192            0x0002040000204000L, 0x0002040000204001L, 0x0002040000204080L, 0x0002040000204081L,
 1193            0x0002040010000000L, 0x0002040010000001L, 0x0002040010000080L, 0x0002040010000081L,
 1194            0x0002040010004000L, 0x0002040010004001L, 0x0002040010004080L, 0x0002040010004081L,
 1195            0x0002040010200000L, 0x0002040010200001L, 0x0002040010200080L, 0x0002040010200081L,
 1196            0x0002040010204000L, 0x0002040010204001L, 0x0002040010204080L, 0x0002040010204081L,
 1197            0x0002040800000000L, 0x0002040800000001L, 0x0002040800000080L, 0x0002040800000081L,
 1198            0x0002040800004000L, 0x0002040800004001L, 0x0002040800004080L, 0x0002040800004081L,
 1199            0x0002040800200000L, 0x0002040800200001L, 0x0002040800200080L, 0x0002040800200081L,
 1200            0x0002040800204000L, 0x0002040800204001L, 0x0002040800204080L, 0x0002040800204081L,
 1201            0x0002040810000000L, 0x0002040810000001L, 0x0002040810000080L, 0x0002040810000081L,
 1202            0x0002040810004000L, 0x0002040810004001L, 0x0002040810004080L, 0x0002040810004081L,
 1203            0x0002040810200000L, 0x0002040810200001L, 0x0002040810200080L, 0x0002040810200081L,
 1204            0x0002040810204000L, 0x0002040810204001L, 0x0002040810204080L, 0x0002040810204081L,
 1205            0x0100000000000000L, 0x0100000000000001L, 0x0100000000000080L, 0x0100000000000081L,
 1206            0x0100000000004000L, 0x0100000000004001L, 0x0100000000004080L, 0x0100000000004081L,
 1207            0x0100000000200000L, 0x0100000000200001L, 0x0100000000200080L, 0x0100000000200081L,
 1208            0x0100000000204000L, 0x0100000000204001L, 0x0100000000204080L, 0x0100000000204081L,
 1209            0x0100000010000000L, 0x0100000010000001L, 0x0100000010000080L, 0x0100000010000081L,
 1210            0x0100000010004000L, 0x0100000010004001L, 0x0100000010004080L, 0x0100000010004081L,
 1211            0x0100000010200000L, 0x0100000010200001L, 0x0100000010200080L, 0x0100000010200081L,
 1212            0x0100000010204000L, 0x0100000010204001L, 0x0100000010204080L, 0x0100000010204081L,
 1213            0x0100000800000000L, 0x0100000800000001L, 0x0100000800000080L, 0x0100000800000081L,
 1214            0x0100000800004000L, 0x0100000800004001L, 0x0100000800004080L, 0x0100000800004081L,
 1215            0x0100000800200000L, 0x0100000800200001L, 0x0100000800200080L, 0x0100000800200081L,
 1216            0x0100000800204000L, 0x0100000800204001L, 0x0100000800204080L, 0x0100000800204081L,
 1217            0x0100000810000000L, 0x0100000810000001L, 0x0100000810000080L, 0x0100000810000081L,
 1218            0x0100000810004000L, 0x0100000810004001L, 0x0100000810004080L, 0x0100000810004081L,
 1219            0x0100000810200000L, 0x0100000810200001L, 0x0100000810200080L, 0x0100000810200081L,
 1220            0x0100000810204000L, 0x0100000810204001L, 0x0100000810204080L, 0x0100000810204081L,
 1221            0x0100040000000000L, 0x0100040000000001L, 0x0100040000000080L, 0x0100040000000081L,
 1222            0x0100040000004000L, 0x0100040000004001L, 0x0100040000004080L, 0x0100040000004081L,
 1223            0x0100040000200000L, 0x0100040000200001L, 0x0100040000200080L, 0x0100040000200081L,
 1224            0x0100040000204000L, 0x0100040000204001L, 0x0100040000204080L, 0x0100040000204081L,
 1225            0x0100040010000000L, 0x0100040010000001L, 0x0100040010000080L, 0x0100040010000081L,
 1226            0x0100040010004000L, 0x0100040010004001L, 0x0100040010004080L, 0x0100040010004081L,
 1227            0x0100040010200000L, 0x0100040010200001L, 0x0100040010200080L, 0x0100040010200081L,
 1228            0x0100040010204000L, 0x0100040010204001L, 0x0100040010204080L, 0x0100040010204081L,
 1229            0x0100040800000000L, 0x0100040800000001L, 0x0100040800000080L, 0x0100040800000081L,
 1230            0x0100040800004000L, 0x0100040800004001L, 0x0100040800004080L, 0x0100040800004081L,
 1231            0x0100040800200000L, 0x0100040800200001L, 0x0100040800200080L, 0x0100040800200081L,
 1232            0x0100040800204000L, 0x0100040800204001L, 0x0100040800204080L, 0x0100040800204081L,
 1233            0x0100040810000000L, 0x0100040810000001L, 0x0100040810000080L, 0x0100040810000081L,
 1234            0x0100040810004000L, 0x0100040810004001L, 0x0100040810004080L, 0x0100040810004081L,
 1235            0x0100040810200000L, 0x0100040810200001L, 0x0100040810200080L, 0x0100040810200081L,
 1236            0x0100040810204000L, 0x0100040810204001L, 0x0100040810204080L, 0x0100040810204081L,
 1237            0x0102000000000000L, 0x0102000000000001L, 0x0102000000000080L, 0x0102000000000081L,
 1238            0x0102000000004000L, 0x0102000000004001L, 0x0102000000004080L, 0x0102000000004081L,
 1239            0x0102000000200000L, 0x0102000000200001L, 0x0102000000200080L, 0x0102000000200081L,
 1240            0x0102000000204000L, 0x0102000000204001L, 0x0102000000204080L, 0x0102000000204081L,
 1241            0x0102000010000000L, 0x0102000010000001L, 0x0102000010000080L, 0x0102000010000081L,
 1242            0x0102000010004000L, 0x0102000010004001L, 0x0102000010004080L, 0x0102000010004081L,
 1243            0x0102000010200000L, 0x0102000010200001L, 0x0102000010200080L, 0x0102000010200081L,
 1244            0x0102000010204000L, 0x0102000010204001L, 0x0102000010204080L, 0x0102000010204081L,
 1245            0x0102000800000000L, 0x0102000800000001L, 0x0102000800000080L, 0x0102000800000081L,
 1246            0x0102000800004000L, 0x0102000800004001L, 0x0102000800004080L, 0x0102000800004081L,
 1247            0x0102000800200000L, 0x0102000800200001L, 0x0102000800200080L, 0x0102000800200081L,
 1248            0x0102000800204000L, 0x0102000800204001L, 0x0102000800204080L, 0x0102000800204081L,
 1249            0x0102000810000000L, 0x0102000810000001L, 0x0102000810000080L, 0x0102000810000081L,
 1250            0x0102000810004000L, 0x0102000810004001L, 0x0102000810004080L, 0x0102000810004081L,
 1251            0x0102000810200000L, 0x0102000810200001L, 0x0102000810200080L, 0x0102000810200081L,
 1252            0x0102000810204000L, 0x0102000810204001L, 0x0102000810204080L, 0x0102000810204081L,
 1253            0x0102040000000000L, 0x0102040000000001L, 0x0102040000000080L, 0x0102040000000081L,
 1254            0x0102040000004000L, 0x0102040000004001L, 0x0102040000004080L, 0x0102040000004081L,
 1255            0x0102040000200000L, 0x0102040000200001L, 0x0102040000200080L, 0x0102040000200081L,
 1256            0x0102040000204000L, 0x0102040000204001L, 0x0102040000204080L, 0x0102040000204081L,
 1257            0x0102040010000000L, 0x0102040010000001L, 0x0102040010000080L, 0x0102040010000081L,
 1258            0x0102040010004000L, 0x0102040010004001L, 0x0102040010004080L, 0x0102040010004081L,
 1259            0x0102040010200000L, 0x0102040010200001L, 0x0102040010200080L, 0x0102040010200081L,
 1260            0x0102040010204000L, 0x0102040010204001L, 0x0102040010204080L, 0x0102040010204081L,
 1261            0x0102040800000000L, 0x0102040800000001L, 0x0102040800000080L, 0x0102040800000081L,
 1262            0x0102040800004000L, 0x0102040800004001L, 0x0102040800004080L, 0x0102040800004081L,
 1263            0x0102040800200000L, 0x0102040800200001L, 0x0102040800200080L, 0x0102040800200081L,
 1264            0x0102040800204000L, 0x0102040800204001L, 0x0102040800204080L, 0x0102040800204081L,
 1265            0x0102040810000000L, 0x0102040810000001L, 0x0102040810000080L, 0x0102040810000081L,
 1266            0x0102040810004000L, 0x0102040810004001L, 0x0102040810004080L, 0x0102040810004081L,
 1267            0x0102040810200000L, 0x0102040810200001L, 0x0102040810200080L, 0x0102040810200081L,
 1268            0x0102040810204000L, 0x0102040810204001L, 0x0102040810204080L, 0x0102040810204081L
 1269        };
 270
 271        // For toString(); must have length 64
 272        private const string ZEROES = "0000000000000000000000000000000000000000000000000000000000000000";
 273
 1274        internal static readonly byte[] BitLengths =
 1275        {
 1276            0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
 1277            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 1278            6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
 1279            6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
 1280            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 1281            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 1282            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 1283            7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 1284            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 1285            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 1286            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 1287            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 1288            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 1289            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 1290            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 1291            8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
 1292        };
 293
 294        // TODO make m fixed for the LongArray, and hence compute T once and for all
 295
 296        private long[] m_ints;
 297
 0298        public LongArray(int intLen)
 0299        {
 0300            m_ints = new long[intLen];
 0301        }
 302
 0303        public LongArray(long[] ints)
 0304        {
 0305            m_ints = ints;
 0306        }
 307
 0308        public LongArray(long[] ints, int off, int len)
 0309        {
 0310            if (off == 0 && len == ints.Length)
 0311            {
 0312                m_ints = ints;
 0313            }
 314            else
 0315            {
 0316                m_ints = new long[len];
 0317                Array.Copy(ints, off, m_ints, 0, len);
 0318            }
 0319        }
 320
 0321        public LongArray(BigInteger bigInt)
 0322        {
 0323            if (bigInt == null || bigInt.SignValue < 0)
 0324            {
 0325                throw new ArgumentException("invalid F2m field value", "bigInt");
 326            }
 327
 0328            if (bigInt.SignValue == 0)
 0329            {
 0330                m_ints = new long[] { 0L };
 0331                return;
 332            }
 333
 0334            byte[] barr = bigInt.ToByteArray();
 0335            int barrLen = barr.Length;
 0336            int barrStart = 0;
 0337            if (barr[0] == 0)
 0338            {
 339                // First byte is 0 to enforce highest (=sign) bit is zero.
 340                // In this case ignore barr[0].
 0341                barrLen--;
 0342                barrStart = 1;
 0343            }
 0344            int intLen = (barrLen + 7) / 8;
 0345            m_ints = new long[intLen];
 346
 0347            int iarrJ = intLen - 1;
 0348            int rem = barrLen % 8 + barrStart;
 0349            long temp = 0;
 0350            int barrI = barrStart;
 0351            if (barrStart < rem)
 0352            {
 0353                for (; barrI < rem; barrI++)
 0354                {
 0355                    temp <<= 8;
 0356                    uint barrBarrI = barr[barrI];
 0357                    temp |= barrBarrI;
 0358                }
 0359                m_ints[iarrJ--] = temp;
 0360            }
 361
 0362            for (; iarrJ >= 0; iarrJ--)
 0363            {
 0364                temp = 0;
 0365                for (int i = 0; i < 8; i++)
 0366                {
 0367                    temp <<= 8;
 0368                    uint barrBarrI = barr[barrI++];
 0369                    temp |= barrBarrI;
 0370                }
 0371                m_ints[iarrJ] = temp;
 0372            }
 0373        }
 374
 375        internal void CopyTo(long[] z, int zOff)
 0376        {
 0377            Array.Copy(m_ints, 0, z, zOff, m_ints.Length);
 0378        }
 379
 380        public bool IsOne()
 0381        {
 0382            long[] a = m_ints;
 0383            if (a[0] != 1L)
 0384            {
 0385                return false;
 386            }
 0387            for (int i = 1; i < a.Length; ++i)
 0388            {
 0389                if (a[i] != 0L)
 0390                {
 0391                    return false;
 392                }
 0393            }
 0394            return true;
 0395        }
 396
 397        public bool IsZero()
 0398        {
 0399            long[] a = m_ints;
 0400            for (int i = 0; i < a.Length; ++i)
 0401            {
 0402                if (a[i] != 0L)
 0403                {
 0404                    return false;
 405                }
 0406            }
 0407            return true;
 0408        }
 409
 410        public int GetUsedLength()
 0411        {
 0412            return GetUsedLengthFrom(m_ints.Length);
 0413        }
 414
 415        public int GetUsedLengthFrom(int from)
 0416        {
 0417            long[] a = m_ints;
 0418            from = System.Math.Min(from, a.Length);
 419
 0420            if (from < 1)
 0421            {
 0422                return 0;
 423            }
 424
 425            // Check if first element will act as sentinel
 0426            if (a[0] != 0)
 0427            {
 0428                while (a[--from] == 0)
 0429                {
 0430                }
 0431                return from + 1;
 432            }
 433
 434            do
 0435            {
 0436                if (a[--from] != 0)
 0437                {
 0438                    return from + 1;
 439                }
 0440            }
 0441            while (from > 0);
 442
 0443            return 0;
 0444        }
 445
 446        public int Degree()
 0447        {
 0448            int i = m_ints.Length;
 449            long w;
 450            do
 0451            {
 0452                if (i == 0)
 0453                {
 0454                    return 0;
 455                }
 0456                w = m_ints[--i];
 0457            }
 0458            while (w == 0);
 459
 0460            return (i << 6) + BitLength(w);
 0461        }
 462
 463        private int DegreeFrom(int limit)
 0464        {
 0465            int i = (int)(((uint)limit + 62) >> 6);
 466            long w;
 467            do
 0468            {
 0469                if (i == 0)
 0470                {
 0471                    return 0;
 472                }
 0473                w = m_ints[--i];
 0474            }
 0475            while (w == 0);
 476
 0477            return (i << 6) + BitLength(w);
 0478        }
 479
 480    //    private int lowestCoefficient()
 481    //    {
 482    //        for (int i = 0; i < m_ints.Length; ++i)
 483    //        {
 484    //            long mi = m_ints[i];
 485    //            if (mi != 0)
 486    //            {
 487    //                int j = 0;
 488    //                while ((mi & 0xFFL) == 0)
 489    //                {
 490    //                    j += 8;
 491    //                    mi >>>= 8;
 492    //                }
 493    //                while ((mi & 1L) == 0)
 494    //                {
 495    //                    ++j;
 496    //                    mi >>>= 1;
 497    //                }
 498    //                return (i << 6) + j;
 499    //            }
 500    //        }
 501    //        return -1;
 502    //    }
 503
 504        private static int BitLength(long w)
 0505        {
 0506            int u = (int)((ulong)w >> 32), b;
 0507            if (u == 0)
 0508            {
 0509                u = (int)w;
 0510                b = 0;
 0511            }
 512            else
 0513            {
 0514                b = 32;
 0515            }
 516
 0517            int t = (int)((uint)u >> 16), k;
 0518            if (t == 0)
 0519            {
 0520                t = (int)((uint)u >> 8);
 0521                k = (t == 0) ? BitLengths[u] : 8 + BitLengths[t];
 0522            }
 523            else
 0524            {
 0525                int v = (int)((uint)t >> 8);
 0526                k = (v == 0) ? 16 + BitLengths[t] : 24 + BitLengths[v];
 0527            }
 528
 0529            return b + k;
 0530        }
 531
 532        private long[] ResizedInts(int newLen)
 0533        {
 0534            long[] newInts = new long[newLen];
 0535            Array.Copy(m_ints, 0, newInts, 0, System.Math.Min(m_ints.Length, newLen));
 0536            return newInts;
 0537        }
 538
 539        public BigInteger ToBigInteger()
 0540        {
 0541            int usedLen = GetUsedLength();
 0542            if (usedLen == 0)
 0543            {
 0544                return BigInteger.Zero;
 545            }
 546
 0547            long highestInt = m_ints[usedLen - 1];
 0548            byte[] temp = new byte[8];
 0549            int barrI = 0;
 0550            bool trailingZeroBytesDone = false;
 0551            for (int j = 7; j >= 0; j--)
 0552            {
 0553                byte thisByte = (byte)((ulong)highestInt >> (8 * j));
 0554                if (trailingZeroBytesDone || (thisByte != 0))
 0555                {
 0556                    trailingZeroBytesDone = true;
 0557                    temp[barrI++] = thisByte;
 0558                }
 0559            }
 560
 0561            int barrLen = 8 * (usedLen - 1) + barrI;
 0562            byte[] barr = new byte[barrLen];
 0563            for (int j = 0; j < barrI; j++)
 0564            {
 0565                barr[j] = temp[j];
 0566            }
 567            // Highest value int is done now
 568
 0569            for (int iarrJ = usedLen - 2; iarrJ >= 0; iarrJ--)
 0570            {
 0571                long mi = m_ints[iarrJ];
 0572                for (int j = 7; j >= 0; j--)
 0573                {
 0574                    barr[barrI++] = (byte)((ulong)mi >> (8 * j));
 0575                }
 0576            }
 0577            return new BigInteger(1, barr);
 0578        }
 579
 580    //    private static long shiftUp(long[] x, int xOff, int count)
 581    //    {
 582    //        long prev = 0;
 583    //        for (int i = 0; i < count; ++i)
 584    //        {
 585    //            long next = x[xOff + i];
 586    //            x[xOff + i] = (next << 1) | prev;
 587    //            prev = next >>> 63;
 588    //        }
 589    //        return prev;
 590    //    }
 591
 592        private static long ShiftUp(long[] x, int xOff, int count, int shift)
 0593        {
 0594            int shiftInv = 64 - shift;
 0595            long prev = 0;
 0596            for (int i = 0; i < count; ++i)
 0597            {
 0598                long next = x[xOff + i];
 0599                x[xOff + i] = (next << shift) | prev;
 0600                prev = (long)((ulong)next >> shiftInv);
 0601            }
 0602            return prev;
 0603        }
 604
 605        private static long ShiftUp(long[] x, int xOff, long[] z, int zOff, int count, int shift)
 0606        {
 0607            int shiftInv = 64 - shift;
 0608            long prev = 0;
 0609            for (int i = 0; i < count; ++i)
 0610            {
 0611                long next = x[xOff + i];
 0612                z[zOff + i] = (next << shift) | prev;
 0613                prev = (long)((ulong)next >> shiftInv);
 0614            }
 0615            return prev;
 0616        }
 617
 618        public LongArray AddOne()
 0619        {
 0620            if (m_ints.Length == 0)
 0621            {
 0622                return new LongArray(new long[]{ 1L });
 623            }
 624
 0625            int resultLen = System.Math.Max(1, GetUsedLength());
 0626            long[] ints = ResizedInts(resultLen);
 0627            ints[0] ^= 1L;
 0628            return new LongArray(ints);
 0629        }
 630
 631    //    private void addShiftedByBits(LongArray other, int bits)
 632    //    {
 633    //        int words = bits >>> 6;
 634    //        int shift = bits & 0x3F;
 635    //
 636    //        if (shift == 0)
 637    //        {
 638    //            addShiftedByWords(other, words);
 639    //            return;
 640    //        }
 641    //
 642    //        int otherUsedLen = other.GetUsedLength();
 643    //        if (otherUsedLen == 0)
 644    //        {
 645    //            return;
 646    //        }
 647    //
 648    //        int minLen = otherUsedLen + words + 1;
 649    //        if (minLen > m_ints.Length)
 650    //        {
 651    //            m_ints = resizedInts(minLen);
 652    //        }
 653    //
 654    //        long carry = addShiftedByBits(m_ints, words, other.m_ints, 0, otherUsedLen, shift);
 655    //        m_ints[otherUsedLen + words] ^= carry;
 656    //    }
 657
 658        private void AddShiftedByBitsSafe(LongArray other, int otherDegree, int bits)
 0659        {
 0660            int otherLen = (int)((uint)(otherDegree + 63) >> 6);
 661
 0662            int words = (int)((uint)bits >> 6);
 0663            int shift = bits & 0x3F;
 664
 0665            if (shift == 0)
 0666            {
 0667                Add(m_ints, words, other.m_ints, 0, otherLen);
 0668                return;
 669            }
 670
 0671            long carry = AddShiftedUp(m_ints, words, other.m_ints, 0, otherLen, shift);
 0672            if (carry != 0L)
 0673            {
 0674                m_ints[otherLen + words] ^= carry;
 0675            }
 0676        }
 677
 678        private static long AddShiftedUp(long[] x, int xOff, long[] y, int yOff, int count, int shift)
 0679        {
 0680            int shiftInv = 64 - shift;
 0681            long prev = 0;
 0682            for (int i = 0; i < count; ++i)
 0683            {
 0684                long next = y[yOff + i];
 0685                x[xOff + i] ^= (next << shift) | prev;
 0686                prev = (long)((ulong)next >> shiftInv);
 0687            }
 0688            return prev;
 0689        }
 690
 691        private static long AddShiftedDown(long[] x, int xOff, long[] y, int yOff, int count, int shift)
 0692        {
 0693            int shiftInv = 64 - shift;
 0694            long prev = 0;
 0695            int i = count;
 0696            while (--i >= 0)
 0697            {
 0698                long next = y[yOff + i];
 0699                x[xOff + i] ^= (long)((ulong)next >> shift) | prev;
 0700                prev = next << shiftInv;
 0701            }
 0702            return prev;
 0703        }
 704
 705        public void AddShiftedByWords(LongArray other, int words)
 0706        {
 0707            int otherUsedLen = other.GetUsedLength();
 0708            if (otherUsedLen == 0)
 0709            {
 0710                return;
 711            }
 712
 0713            int minLen = otherUsedLen + words;
 0714            if (minLen > m_ints.Length)
 0715            {
 0716                m_ints = ResizedInts(minLen);
 0717            }
 718
 0719            Add(m_ints, words, other.m_ints, 0, otherUsedLen);
 0720        }
 721
 722        private static void Add(long[] x, int xOff, long[] y, int yOff, int count)
 0723        {
 0724            for (int i = 0; i < count; ++i)
 0725            {
 0726                x[xOff + i] ^= y[yOff + i];
 0727            }
 0728        }
 729
 730        private static void Add(long[] x, int xOff, long[] y, int yOff, long[] z, int zOff, int count)
 0731        {
 0732            for (int i = 0; i < count; ++i)
 0733            {
 0734                z[zOff + i] = x[xOff + i] ^ y[yOff + i];
 0735            }
 0736        }
 737
 738        private static void AddBoth(long[] x, int xOff, long[] y1, int y1Off, long[] y2, int y2Off, int count)
 0739        {
 0740            for (int i = 0; i < count; ++i)
 0741            {
 0742                x[xOff + i] ^= y1[y1Off + i] ^ y2[y2Off + i];
 0743            }
 0744        }
 745
 746        private static void Distribute(long[] x, int src, int dst1, int dst2, int count)
 0747        {
 0748            for (int i = 0; i < count; ++i)
 0749            {
 0750                long v = x[src + i];
 0751                x[dst1 + i] ^= v;
 0752                x[dst2 + i] ^= v;
 0753            }
 0754        }
 755
 756        public int Length
 757        {
 0758            get { return m_ints.Length; }
 759        }
 760
 761        private static void FlipWord(long[] buf, int off, int bit, long word)
 0762        {
 0763            int n = off + (int)((uint)bit >> 6);
 0764            int shift = bit & 0x3F;
 0765            if (shift == 0)
 0766            {
 0767                buf[n] ^= word;
 0768            }
 769            else
 0770            {
 0771                buf[n] ^= word << shift;
 0772                word = (long)((ulong)word >> (64 - shift));
 0773                if (word != 0)
 0774                {
 0775                    buf[++n] ^= word;
 0776                }
 0777            }
 0778        }
 779
 780    //    private static long getWord(long[] buf, int off, int len, int bit)
 781    //    {
 782    //        int n = off + (bit >>> 6);
 783    //        int shift = bit & 0x3F;
 784    //        if (shift == 0)
 785    //        {
 786    //            return buf[n];
 787    //        }
 788    //        long result = buf[n] >>> shift;
 789    //        if (++n < len)
 790    //        {
 791    //            result |= buf[n] << (64 - shift);
 792    //        }
 793    //        return result;
 794    //    }
 795
 796        public bool TestBitZero()
 0797        {
 0798            return m_ints.Length > 0 && (m_ints[0] & 1L) != 0;
 0799        }
 800
 801        private static bool TestBit(long[] buf, int off, int n)
 0802        {
 803            // theInt = n / 64
 0804            int theInt = (int)((uint)n >> 6);
 805            // theBit = n % 64
 0806            int theBit = n & 0x3F;
 0807            long tester = 1L << theBit;
 0808            return (buf[off + theInt] & tester) != 0;
 0809        }
 810
 811        private static void FlipBit(long[] buf, int off, int n)
 0812        {
 813            // theInt = n / 64
 0814            int theInt = (int)((uint)n >> 6);
 815            // theBit = n % 64
 0816            int theBit = n & 0x3F;
 0817            long flipper = 1L << theBit;
 0818            buf[off + theInt] ^= flipper;
 0819        }
 820
 821    //    private static void SetBit(long[] buf, int off, int n)
 822    //    {
 823    //        // theInt = n / 64
 824    //        int theInt = n >>> 6;
 825    //        // theBit = n % 64
 826    //        int theBit = n & 0x3F;
 827    //        long setter = 1L << theBit;
 828    //        buf[off + theInt] |= setter;
 829    //    }
 830    //
 831    //    private static void ClearBit(long[] buf, int off, int n)
 832    //    {
 833    //        // theInt = n / 64
 834    //        int theInt = n >>> 6;
 835    //        // theBit = n % 64
 836    //        int theBit = n & 0x3F;
 837    //        long setter = 1L << theBit;
 838    //        buf[off + theInt] &= ~setter;
 839    //    }
 840
 841        private static void MultiplyWord(long a, long[] b, int bLen, long[] c, int cOff)
 0842        {
 0843            if ((a & 1L) != 0L)
 0844            {
 0845                Add(c, cOff, b, 0, bLen);
 0846            }
 0847            int k = 1;
 0848            while ((a = (long)((ulong)a >> 1)) != 0L)
 0849            {
 0850                if ((a & 1L) != 0L)
 0851                {
 0852                    long carry = AddShiftedUp(c, cOff, b, 0, bLen, k);
 0853                    if (carry != 0L)
 0854                    {
 0855                        c[cOff + bLen] ^= carry;
 0856                    }
 0857                }
 0858                ++k;
 0859            }
 0860        }
 861
 862        public LongArray ModMultiplyLD(LongArray other, int m, int[] ks)
 0863        {
 864            /*
 865             * Find out the degree of each argument and handle the zero cases
 866             */
 0867            int aDeg = Degree();
 0868            if (aDeg == 0)
 0869            {
 0870                return this;
 871            }
 0872            int bDeg = other.Degree();
 0873            if (bDeg == 0)
 0874            {
 0875                return other;
 876            }
 877
 878            /*
 879             * Swap if necessary so that A is the smaller argument
 880             */
 0881            LongArray A = this, B = other;
 0882            if (aDeg > bDeg)
 0883            {
 0884                A = other; B = this;
 0885                int tmp = aDeg; aDeg = bDeg; bDeg = tmp;
 0886            }
 887
 888            /*
 889             * Establish the word lengths of the arguments and result
 890             */
 0891            int aLen = (int)((uint)(aDeg + 63) >> 6);
 0892            int bLen = (int)((uint)(bDeg + 63) >> 6);
 0893            int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6);
 894
 0895            if (aLen == 1)
 0896            {
 0897                long a0 = A.m_ints[0];
 0898                if (a0 == 1L)
 0899                {
 0900                    return B;
 901                }
 902
 903                /*
 904                 * Fast path for small A, with performance dependent only on the number of set bits
 905                 */
 0906                long[] c0 = new long[cLen];
 0907                MultiplyWord(a0, B.m_ints, bLen, c0, 0);
 908
 909                /*
 910                 * Reduce the raw answer against the reduction coefficients
 911                 */
 0912                return ReduceResult(c0, 0, cLen, m, ks);
 913            }
 914
 915            /*
 916             * Determine if B will get bigger during shifting
 917             */
 0918            int bMax = (int)((uint)(bDeg + 7 + 63) >> 6);
 919
 920            /*
 921             * Lookup table for the offset of each B in the tables
 922             */
 0923            int[] ti = new int[16];
 924
 925            /*
 926             * Precompute table of all 4-bit products of B
 927             */
 0928            long[] T0 = new long[bMax << 4];
 0929            int tOff = bMax;
 0930            ti[1] = tOff;
 0931            Array.Copy(B.m_ints, 0, T0, tOff, bLen);
 0932            for (int i = 2; i < 16; ++i)
 0933            {
 0934                ti[i] = (tOff += bMax);
 0935                if ((i & 1) == 0)
 0936                {
 0937                    ShiftUp(T0, (int)((uint)tOff >> 1), T0, tOff, bMax, 1);
 0938                }
 939                else
 0940                {
 0941                    Add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax);
 0942                }
 0943            }
 944
 945            /*
 946             * Second table with all 4-bit products of B shifted 4 bits
 947             */
 0948            long[] T1 = new long[T0.Length];
 0949            ShiftUp(T0, 0, T1, 0, T0.Length, 4);
 950    //        shiftUp(T0, bMax, T1, bMax, tOff, 4);
 951
 0952            long[] a = A.m_ints;
 0953            long[] c = new long[cLen];
 954
 0955            int MASK = 0xF;
 956
 957            /*
 958             * Lopez-Dahab algorithm
 959             */
 960
 0961            for (int k = 56; k >= 0; k -= 8)
 0962            {
 0963                for (int j = 1; j < aLen; j += 2)
 0964                {
 0965                    int aVal = (int)((ulong)a[j] >> k);
 0966                    int u = aVal & MASK;
 0967                    int v = (int)((uint)aVal >> 4) & MASK;
 0968                    AddBoth(c, j - 1, T0, ti[u], T1, ti[v], bMax);
 0969                }
 0970                ShiftUp(c, 0, cLen, 8);
 0971            }
 972
 0973            for (int k = 56; k >= 0; k -= 8)
 0974            {
 0975                for (int j = 0; j < aLen; j += 2)
 0976                {
 0977                    int aVal = (int)((ulong)a[j] >> k);
 0978                    int u = aVal & MASK;
 0979                    int v = (int)((uint)aVal >> 4) & MASK;
 0980                    AddBoth(c, j, T0, ti[u], T1, ti[v], bMax);
 0981                }
 0982                if (k > 0)
 0983                {
 0984                    ShiftUp(c, 0, cLen, 8);
 0985                }
 0986            }
 987
 988            /*
 989             * Finally the raw answer is collected, reduce it against the reduction coefficients
 990             */
 0991            return ReduceResult(c, 0, cLen, m, ks);
 0992        }
 993
 994        public LongArray ModMultiply(LongArray other, int m, int[] ks)
 0995        {
 996            /*
 997             * Find out the degree of each argument and handle the zero cases
 998             */
 0999            int aDeg = Degree();
 01000            if (aDeg == 0)
 01001            {
 01002                return this;
 1003            }
 01004            int bDeg = other.Degree();
 01005            if (bDeg == 0)
 01006            {
 01007                return other;
 1008            }
 1009
 1010            /*
 1011             * Swap if necessary so that A is the smaller argument
 1012             */
 01013            LongArray A = this, B = other;
 01014            if (aDeg > bDeg)
 01015            {
 01016                A = other; B = this;
 01017                int tmp = aDeg; aDeg = bDeg; bDeg = tmp;
 01018            }
 1019
 1020            /*
 1021             * Establish the word lengths of the arguments and result
 1022             */
 01023            int aLen = (int)((uint)(aDeg + 63) >> 6);
 01024            int bLen = (int)((uint)(bDeg + 63) >> 6);
 01025            int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6);
 1026
 01027            if (aLen == 1)
 01028            {
 01029                long a0 = A.m_ints[0];
 01030                if (a0 == 1L)
 01031                {
 01032                    return B;
 1033                }
 1034
 1035                /*
 1036                 * Fast path for small A, with performance dependent only on the number of set bits
 1037                 */
 01038                long[] c0 = new long[cLen];
 01039                MultiplyWord(a0, B.m_ints, bLen, c0, 0);
 1040
 1041                /*
 1042                 * Reduce the raw answer against the reduction coefficients
 1043                 */
 01044                return ReduceResult(c0, 0, cLen, m, ks);
 1045            }
 1046
 1047            /*
 1048             * Determine if B will get bigger during shifting
 1049             */
 01050            int bMax = (int)((uint)(bDeg + 7 + 63) >> 6);
 1051
 1052            /*
 1053             * Lookup table for the offset of each B in the tables
 1054             */
 01055            int[] ti = new int[16];
 1056
 1057            /*
 1058             * Precompute table of all 4-bit products of B
 1059             */
 01060            long[] T0 = new long[bMax << 4];
 01061            int tOff = bMax;
 01062            ti[1] = tOff;
 01063            Array.Copy(B.m_ints, 0, T0, tOff, bLen);
 01064            for (int i = 2; i < 16; ++i)
 01065            {
 01066                ti[i] = (tOff += bMax);
 01067                if ((i & 1) == 0)
 01068                {
 01069                    ShiftUp(T0, (int)((uint)tOff >> 1), T0, tOff, bMax, 1);
 01070                }
 1071                else
 01072                {
 01073                    Add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax);
 01074                }
 01075            }
 1076
 1077            /*
 1078             * Second table with all 4-bit products of B shifted 4 bits
 1079             */
 01080            long[] T1 = new long[T0.Length];
 01081            ShiftUp(T0, 0, T1, 0, T0.Length, 4);
 1082    //        ShiftUp(T0, bMax, T1, bMax, tOff, 4);
 1083
 01084            long[] a = A.m_ints;
 01085            long[] c = new long[cLen << 3];
 1086
 01087            int MASK = 0xF;
 1088
 1089            /*
 1090             * Lopez-Dahab (Modified) algorithm
 1091             */
 1092
 01093            for (int aPos = 0; aPos < aLen; ++aPos)
 01094            {
 01095                long aVal = a[aPos];
 01096                int cOff = aPos;
 1097                for (;;)
 01098                {
 01099                    int u = (int)aVal & MASK;
 01100                    aVal = (long)((ulong)aVal >> 4);
 01101                    int v = (int)aVal & MASK;
 01102                    AddBoth(c, cOff, T0, ti[u], T1, ti[v], bMax);
 01103                    aVal = (long)((ulong)aVal >> 4);
 01104                    if (aVal == 0L)
 01105                    {
 01106                        break;
 1107                    }
 01108                    cOff += cLen;
 01109                }
 01110            }
 1111
 01112            {
 01113                int cOff = c.Length;
 01114                while ((cOff -= cLen) != 0)
 01115                {
 01116                    AddShiftedUp(c, cOff - cLen, c, cOff, cLen, 8);
 01117                }
 01118            }
 1119
 1120            /*
 1121             * Finally the raw answer is collected, reduce it against the reduction coefficients
 1122             */
 01123            return ReduceResult(c, 0, cLen, m, ks);
 01124        }
 1125
 1126        public LongArray ModMultiplyAlt(LongArray other, int m, int[] ks)
 01127        {
 1128            /*
 1129             * Find out the degree of each argument and handle the zero cases
 1130             */
 01131            int aDeg = Degree();
 01132            if (aDeg == 0)
 01133            {
 01134                return this;
 1135            }
 01136            int bDeg = other.Degree();
 01137            if (bDeg == 0)
 01138            {
 01139                return other;
 1140            }
 1141
 1142            /*
 1143             * Swap if necessary so that A is the smaller argument
 1144             */
 01145            LongArray A = this, B = other;
 01146            if (aDeg > bDeg)
 01147            {
 01148                A = other; B = this;
 01149                int tmp = aDeg; aDeg = bDeg; bDeg = tmp;
 01150            }
 1151
 1152            /*
 1153             * Establish the word lengths of the arguments and result
 1154             */
 01155            int aLen = (int)((uint)(aDeg + 63) >> 6);
 01156            int bLen = (int)((uint)(bDeg + 63) >> 6);
 01157            int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6);
 1158
 01159            if (aLen == 1)
 01160            {
 01161                long a0 = A.m_ints[0];
 01162                if (a0 == 1L)
 01163                {
 01164                    return B;
 1165                }
 1166
 1167                /*
 1168                 * Fast path for small A, with performance dependent only on the number of set bits
 1169                 */
 01170                long[] c0 = new long[cLen];
 01171                MultiplyWord(a0, B.m_ints, bLen, c0, 0);
 1172
 1173                /*
 1174                 * Reduce the raw answer against the reduction coefficients
 1175                 */
 01176                return ReduceResult(c0, 0, cLen, m, ks);
 1177            }
 1178
 1179            // NOTE: This works, but is slower than width 4 processing
 1180    //        if (aLen == 2)
 1181    //        {
 1182    //            /*
 1183    //             * Use common-multiplicand optimization to save ~1/4 of the adds
 1184    //             */
 1185    //            long a1 = A.m_ints[0], a2 = A.m_ints[1];
 1186    //            long aa = a1 & a2; a1 ^= aa; a2 ^= aa;
 1187    //
 1188    //            long[] b = B.m_ints;
 1189    //            long[] c = new long[cLen];
 1190    //            multiplyWord(aa, b, bLen, c, 1);
 1191    //            add(c, 0, c, 1, cLen - 1);
 1192    //            multiplyWord(a1, b, bLen, c, 0);
 1193    //            multiplyWord(a2, b, bLen, c, 1);
 1194    //
 1195    //            /*
 1196    //             * Reduce the raw answer against the reduction coefficients
 1197    //             */
 1198    //            return ReduceResult(c, 0, cLen, m, ks);
 1199    //        }
 1200
 1201            /*
 1202             * Determine the parameters of the Interleaved window algorithm: the 'width' in bits to
 1203             * process together, the number of evaluation 'positions' implied by that width, and the
 1204             * 'top' position at which the regular window algorithm stops.
 1205             */
 1206            int width, positions, top, banks;
 1207
 1208            // NOTE: width 4 is the fastest over the entire range of sizes used in current crypto
 1209    //        width = 1; positions = 64; top = 64; banks = 4;
 1210    //        width = 2; positions = 32; top = 64; banks = 4;
 1211    //        width = 3; positions = 21; top = 63; banks = 3;
 01212            width = 4; positions = 16; top = 64; banks = 8;
 1213    //        width = 5; positions = 13; top = 65; banks = 7;
 1214    //        width = 7; positions = 9; top = 63; banks = 9;
 1215    //        width = 8; positions = 8; top = 64; banks = 8;
 1216
 1217            /*
 1218             * Determine if B will get bigger during shifting
 1219             */
 01220            int shifts = top < 64 ? positions : positions - 1;
 01221            int bMax = (int)((uint)(bDeg + shifts + 63) >> 6);
 1222
 01223            int bTotal = bMax * banks, stride = width * banks;
 1224
 1225            /*
 1226             * Create a single temporary buffer, with an offset table to find the positions of things in it
 1227             */
 01228            int[] ci = new int[1 << width];
 01229            int cTotal = aLen;
 01230            {
 01231                ci[0] = cTotal;
 01232                cTotal += bTotal;
 01233                ci[1] = cTotal;
 01234                for (int i = 2; i < ci.Length; ++i)
 01235                {
 01236                    cTotal += cLen;
 01237                    ci[i] = cTotal;
 01238                }
 01239                cTotal += cLen;
 01240            }
 1241            // NOTE: Provide a safe dump for "high zeroes" since we are adding 'bMax' and not 'bLen'
 01242            ++cTotal;
 1243
 01244            long[] c = new long[cTotal];
 1245
 1246            // Prepare A in Interleaved form, according to the chosen width
 01247            Interleave(A.m_ints, 0, c, 0, aLen, width);
 1248
 1249            // Make a working copy of B, since we will be shifting it
 01250            {
 01251                int bOff = aLen;
 01252                Array.Copy(B.m_ints, 0, c, bOff, bLen);
 01253                for (int bank = 1; bank < banks; ++bank)
 01254                {
 01255                    ShiftUp(c, aLen, c, bOff += bMax, bMax, bank);
 01256                }
 01257            }
 1258
 1259            /*
 1260             * The main loop analyzes the Interleaved windows in A, and for each non-zero window
 1261             * a single word-array XOR is performed to a carefully selected slice of 'c'. The loop is
 1262             * breadth-first, checking the lowest window in each word, then looping again for the
 1263             * next higher window position.
 1264             */
 01265            int MASK = (1 << width) - 1;
 1266
 01267            int k = 0;
 1268            for (;;)
 01269            {
 01270                int aPos = 0;
 1271                do
 01272                {
 01273                    long aVal = (long)((ulong)c[aPos] >> k);
 01274                    int bank = 0, bOff = aLen;
 1275                    for (;;)
 01276                    {
 01277                        int index = (int)(aVal) & MASK;
 01278                        if (index != 0)
 01279                        {
 1280                            /*
 1281                             * Add to a 'c' buffer based on the bit-pattern of 'index'. Since A is in
 1282                             * Interleaved form, the bits represent the current B shifted by 0, 'positions',
 1283                             * 'positions' * 2, ..., 'positions' * ('width' - 1)
 1284                             */
 01285                            Add(c, aPos + ci[index], c, bOff, bMax);
 01286                        }
 01287                        if (++bank == banks)
 01288                        {
 01289                            break;
 1290                        }
 01291                        bOff += bMax;
 01292                        aVal = (long)((ulong)aVal >> width);
 01293                    }
 01294                }
 01295                while (++aPos < aLen);
 1296
 01297                if ((k += stride) >= top)
 01298                {
 01299                    if (k >= 64)
 01300                    {
 01301                        break;
 1302                    }
 1303
 1304                    /*
 1305                     * Adjustment for window setups with top == 63, the final bit (if any) is processed
 1306                     * as the top-bit of a window
 1307                     */
 01308                    k = 64 - width;
 01309                    MASK &= MASK << (top - k);
 01310                }
 1311
 1312                /*
 1313                 * After each position has been checked for all words of A, B is shifted up 1 place
 1314                 */
 01315                ShiftUp(c, aLen, bTotal, banks);
 01316            }
 1317
 01318            int ciPos = ci.Length;
 01319            while (--ciPos > 1)
 01320            {
 01321                if ((ciPos & 1L) == 0L)
 01322                {
 1323                    /*
 1324                     * For even numbers, shift contents and add to the half-position
 1325                     */
 01326                    AddShiftedUp(c, ci[(uint)ciPos >> 1], c, ci[ciPos], cLen, positions);
 01327                }
 1328                else
 01329                {
 1330                    /*
 1331                     * For odd numbers, 'distribute' contents to the result and the next-lowest position
 1332                     */
 01333                    Distribute(c, ci[ciPos], ci[ciPos - 1], ci[1], cLen);
 01334                }
 01335            }
 1336
 1337            /*
 1338             * Finally the raw answer is collected, reduce it against the reduction coefficients
 1339             */
 01340            return ReduceResult(c, ci[1], cLen, m, ks);
 01341        }
 1342
 1343        public LongArray ModReduce(int m, int[] ks)
 01344        {
 01345            long[] buf = Arrays.Clone(m_ints);
 01346            int rLen = ReduceInPlace(buf, 0, buf.Length, m, ks);
 01347            return new LongArray(buf, 0, rLen);
 01348        }
 1349
 1350        public LongArray Multiply(LongArray other, int m, int[] ks)
 01351        {
 1352            /*
 1353             * Find out the degree of each argument and handle the zero cases
 1354             */
 01355            int aDeg = Degree();
 01356            if (aDeg == 0)
 01357            {
 01358                return this;
 1359            }
 01360            int bDeg = other.Degree();
 01361            if (bDeg == 0)
 01362            {
 01363                return other;
 1364            }
 1365
 1366            /*
 1367             * Swap if necessary so that A is the smaller argument
 1368             */
 01369            LongArray A = this, B = other;
 01370            if (aDeg > bDeg)
 01371            {
 01372                A = other; B = this;
 01373                int tmp = aDeg; aDeg = bDeg; bDeg = tmp;
 01374            }
 1375
 1376            /*
 1377             * Establish the word lengths of the arguments and result
 1378             */
 01379            int aLen = (int)((uint)(aDeg + 63) >> 6);
 01380            int bLen = (int)((uint)(bDeg + 63) >> 6);
 01381            int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6);
 1382
 01383            if (aLen == 1)
 01384            {
 01385                long a0 = A.m_ints[0];
 01386                if (a0 == 1L)
 01387                {
 01388                    return B;
 1389                }
 1390
 1391                /*
 1392                 * Fast path for small A, with performance dependent only on the number of set bits
 1393                 */
 01394                long[] c0 = new long[cLen];
 01395                MultiplyWord(a0, B.m_ints, bLen, c0, 0);
 1396
 1397                /*
 1398                 * Reduce the raw answer against the reduction coefficients
 1399                 */
 1400                //return ReduceResult(c0, 0, cLen, m, ks);
 01401                return new LongArray(c0, 0, cLen);
 1402            }
 1403
 1404            /*
 1405             * Determine if B will get bigger during shifting
 1406             */
 01407            int bMax = (int)((uint)(bDeg + 7 + 63) >> 6);
 1408
 1409            /*
 1410             * Lookup table for the offset of each B in the tables
 1411             */
 01412            int[] ti = new int[16];
 1413
 1414            /*
 1415             * Precompute table of all 4-bit products of B
 1416             */
 01417            long[] T0 = new long[bMax << 4];
 01418            int tOff = bMax;
 01419            ti[1] = tOff;
 01420            Array.Copy(B.m_ints, 0, T0, tOff, bLen);
 01421            for (int i = 2; i < 16; ++i)
 01422            {
 01423                ti[i] = (tOff += bMax);
 01424                if ((i & 1) == 0)
 01425                {
 01426                    ShiftUp(T0, (int)((uint)tOff >> 1), T0, tOff, bMax, 1);
 01427                }
 1428                else
 01429                {
 01430                    Add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax);
 01431                }
 01432            }
 1433
 1434            /*
 1435             * Second table with all 4-bit products of B shifted 4 bits
 1436             */
 01437            long[] T1 = new long[T0.Length];
 01438            ShiftUp(T0, 0, T1, 0, T0.Length, 4);
 1439            //        ShiftUp(T0, bMax, T1, bMax, tOff, 4);
 1440
 01441            long[] a = A.m_ints;
 01442            long[] c = new long[cLen << 3];
 1443
 01444            int MASK = 0xF;
 1445
 1446            /*
 1447             * Lopez-Dahab (Modified) algorithm
 1448             */
 1449
 01450            for (int aPos = 0; aPos < aLen; ++aPos)
 01451            {
 01452                long aVal = a[aPos];
 01453                int cOff = aPos;
 1454                for (; ; )
 01455                {
 01456                    int u = (int)aVal & MASK;
 01457                    aVal = (long)((ulong)aVal >> 4);
 01458                    int v = (int)aVal & MASK;
 01459                    AddBoth(c, cOff, T0, ti[u], T1, ti[v], bMax);
 01460                    aVal = (long)((ulong)aVal >> 4);
 01461                    if (aVal == 0L)
 01462                    {
 01463                        break;
 1464                    }
 01465                    cOff += cLen;
 01466                }
 01467            }
 1468
 01469            {
 01470                int cOff = c.Length;
 01471                while ((cOff -= cLen) != 0)
 01472                {
 01473                    AddShiftedUp(c, cOff - cLen, c, cOff, cLen, 8);
 01474                }
 01475            }
 1476
 1477            /*
 1478             * Finally the raw answer is collected, reduce it against the reduction coefficients
 1479             */
 1480            //return ReduceResult(c, 0, cLen, m, ks);
 01481            return new LongArray(c, 0, cLen);
 01482        }
 1483
 1484        public void Reduce(int m, int[] ks)
 01485        {
 01486            long[] buf = m_ints;
 01487            int rLen = ReduceInPlace(buf, 0, buf.Length, m, ks);
 01488            if (rLen < buf.Length)
 01489            {
 01490                m_ints = new long[rLen];
 01491                Array.Copy(buf, 0, m_ints, 0, rLen);
 01492            }
 01493        }
 1494
 1495        private static LongArray ReduceResult(long[] buf, int off, int len, int m, int[] ks)
 01496        {
 01497            int rLen = ReduceInPlace(buf, off, len, m, ks);
 01498            return new LongArray(buf, off, rLen);
 01499        }
 1500
 1501    //    private static void deInterleave(long[] x, int xOff, long[] z, int zOff, int count, int rounds)
 1502    //    {
 1503    //        for (int i = 0; i < count; ++i)
 1504    //        {
 1505    //            z[zOff + i] = deInterleave(x[zOff + i], rounds);
 1506    //        }
 1507    //    }
 1508    //
 1509    //    private static long deInterleave(long x, int rounds)
 1510    //    {
 1511    //        while (--rounds >= 0)
 1512    //        {
 1513    //            x = deInterleave32(x & DEInterleave_MASK) | (deInterleave32((x >>> 1) & DEInterleave_MASK) << 32);
 1514    //        }
 1515    //        return x;
 1516    //    }
 1517    //
 1518    //    private static long deInterleave32(long x)
 1519    //    {
 1520    //        x = (x | (x >>> 1)) & 0x3333333333333333L;
 1521    //        x = (x | (x >>> 2)) & 0x0F0F0F0F0F0F0F0FL;
 1522    //        x = (x | (x >>> 4)) & 0x00FF00FF00FF00FFL;
 1523    //        x = (x | (x >>> 8)) & 0x0000FFFF0000FFFFL;
 1524    //        x = (x | (x >>> 16)) & 0x00000000FFFFFFFFL;
 1525    //        return x;
 1526    //    }
 1527
 1528        private static int ReduceInPlace(long[] buf, int off, int len, int m, int[] ks)
 01529        {
 01530            int mLen = (m + 63) >> 6;
 01531            if (len < mLen)
 01532            {
 01533                return len;
 1534            }
 1535
 01536            int numBits = System.Math.Min(len << 6, (m << 1) - 1); // TODO use actual degree?
 01537            int excessBits = (len << 6) - numBits;
 01538            while (excessBits >= 64)
 01539            {
 01540                --len;
 01541                excessBits -= 64;
 01542            }
 1543
 01544            int kLen = ks.Length, kMax = ks[kLen - 1], kNext = kLen > 1 ? ks[kLen - 2] : 0;
 01545            int wordWiseLimit = System.Math.Max(m, kMax + 64);
 01546            int vectorableWords = (excessBits + System.Math.Min(numBits - wordWiseLimit, m - kNext)) >> 6;
 01547            if (vectorableWords > 1)
 01548            {
 01549                int vectorWiseWords = len - vectorableWords;
 01550                ReduceVectorWise(buf, off, len, vectorWiseWords, m, ks);
 01551                while (len > vectorWiseWords)
 01552                {
 01553                    buf[off + --len] = 0L;
 01554                }
 01555                numBits = vectorWiseWords << 6;
 01556            }
 1557
 01558            if (numBits > wordWiseLimit)
 01559            {
 01560                ReduceWordWise(buf, off, len, wordWiseLimit, m, ks);
 01561                numBits = wordWiseLimit;
 01562            }
 1563
 01564            if (numBits > m)
 01565            {
 01566                ReduceBitWise(buf, off, numBits, m, ks);
 01567            }
 1568
 01569            return mLen;
 01570        }
 1571
 1572        private static void ReduceBitWise(long[] buf, int off, int BitLength, int m, int[] ks)
 01573        {
 01574            while (--BitLength >= m)
 01575            {
 01576                if (TestBit(buf, off, BitLength))
 01577                {
 01578                    ReduceBit(buf, off, BitLength, m, ks);
 01579                }
 01580            }
 01581        }
 1582
 1583        private static void ReduceBit(long[] buf, int off, int bit, int m, int[] ks)
 01584        {
 01585            FlipBit(buf, off, bit);
 01586            int n = bit - m;
 01587            int j = ks.Length;
 01588            while (--j >= 0)
 01589            {
 01590                FlipBit(buf, off, ks[j] + n);
 01591            }
 01592            FlipBit(buf, off, n);
 01593        }
 1594
 1595        private static void ReduceWordWise(long[] buf, int off, int len, int toBit, int m, int[] ks)
 01596        {
 01597            int toPos = (int)((uint)toBit >> 6);
 1598
 01599            while (--len > toPos)
 01600            {
 01601                long word = buf[off + len];
 01602                if (word != 0)
 01603                {
 01604                    buf[off + len] = 0;
 01605                    ReduceWord(buf, off, (len << 6), word, m, ks);
 01606                }
 01607            }
 1608
 01609            {
 01610                int partial = toBit & 0x3F;
 01611                long word = (long)((ulong)buf[off + toPos] >> partial);
 01612                if (word != 0)
 01613                {
 01614                    buf[off + toPos] ^= word << partial;
 01615                    ReduceWord(buf, off, toBit, word, m, ks);
 01616                }
 01617            }
 01618        }
 1619
 1620        private static void ReduceWord(long[] buf, int off, int bit, long word, int m, int[] ks)
 01621        {
 01622            int offset = bit - m;
 01623            int j = ks.Length;
 01624            while (--j >= 0)
 01625            {
 01626                FlipWord(buf, off, offset + ks[j], word);
 01627            }
 01628            FlipWord(buf, off, offset, word);
 01629        }
 1630
 1631        private static void ReduceVectorWise(long[] buf, int off, int len, int words, int m, int[] ks)
 01632        {
 1633            /*
 1634             * NOTE: It's important we go from highest coefficient to lowest, because for the highest
 1635             * one (only) we allow the ranges to partially overlap, and therefore any changes must take
 1636             * effect for the subsequent lower coefficients.
 1637             */
 01638            int baseBit = (words << 6) - m;
 01639            int j = ks.Length;
 01640            while (--j >= 0)
 01641            {
 01642                FlipVector(buf, off, buf, off + words, len - words, baseBit + ks[j]);
 01643            }
 01644            FlipVector(buf, off, buf, off + words, len - words, baseBit);
 01645        }
 1646
 1647        private static void FlipVector(long[] x, int xOff, long[] y, int yOff, int yLen, int bits)
 01648        {
 01649            xOff += (int)((uint)bits >> 6);
 01650            bits &= 0x3F;
 1651
 01652            if (bits == 0)
 01653            {
 01654                Add(x, xOff, y, yOff, yLen);
 01655            }
 1656            else
 01657            {
 01658                long carry = AddShiftedDown(x, xOff + 1, y, yOff, yLen, 64 - bits);
 01659                x[xOff] ^= carry;
 01660            }
 01661        }
 1662
 1663        public LongArray ModSquare(int m, int[] ks)
 01664        {
 01665            int len = GetUsedLength();
 01666            if (len == 0)
 01667            {
 01668                return this;
 1669            }
 1670
 01671            int _2len = len << 1;
 01672            long[] r = new long[_2len];
 1673
 01674            int pos = 0;
 01675            while (pos < _2len)
 01676            {
 01677                long mi = m_ints[(uint)pos >> 1];
 01678                r[pos++] = Interleave2_32to64((int)mi);
 01679                r[pos++] = Interleave2_32to64((int)((ulong)mi >> 32));
 01680            }
 1681
 01682            return new LongArray(r, 0, ReduceInPlace(r, 0, r.Length, m, ks));
 01683        }
 1684
 1685        public LongArray ModSquareN(int n, int m, int[] ks)
 01686        {
 01687            int len = GetUsedLength();
 01688            if (len == 0)
 01689            {
 01690                return this;
 1691            }
 1692
 01693            int mLen = (m + 63) >> 6;
 01694            long[] r = new long[mLen << 1];
 01695            Array.Copy(m_ints, 0, r, 0, len);
 1696
 01697            while (--n >= 0)
 01698            {
 01699                SquareInPlace(r, len, m, ks);
 01700                len = ReduceInPlace(r, 0, r.Length, m, ks);
 01701            }
 1702
 01703            return new LongArray(r, 0, len);
 01704        }
 1705
 1706        public LongArray Square(int m, int[] ks)
 01707        {
 01708            int len = GetUsedLength();
 01709            if (len == 0)
 01710            {
 01711                return this;
 1712            }
 1713
 01714            int _2len = len << 1;
 01715            long[] r = new long[_2len];
 1716
 01717            int pos = 0;
 01718            while (pos < _2len)
 01719            {
 01720                long mi = m_ints[(uint)pos >> 1];
 01721                r[pos++] = Interleave2_32to64((int)mi);
 01722                r[pos++] = Interleave2_32to64((int)((ulong)mi >> 32));
 01723            }
 1724
 01725            return new LongArray(r, 0, r.Length);
 01726        }
 1727
 1728        private static void SquareInPlace(long[] x, int xLen, int m, int[] ks)
 01729        {
 01730            int pos = xLen << 1;
 01731            while (--xLen >= 0)
 01732            {
 01733                long xVal = x[xLen];
 01734                x[--pos] = Interleave2_32to64((int)((ulong)xVal >> 32));
 01735                x[--pos] = Interleave2_32to64((int)xVal);
 01736            }
 01737        }
 1738
 1739        private static void Interleave(long[] x, int xOff, long[] z, int zOff, int count, int width)
 01740        {
 01741            switch (width)
 1742            {
 1743            case 3:
 01744                Interleave3(x, xOff, z, zOff, count);
 01745                break;
 1746            case 5:
 01747                Interleave5(x, xOff, z, zOff, count);
 01748                break;
 1749            case 7:
 01750                Interleave7(x, xOff, z, zOff, count);
 01751                break;
 1752            default:
 01753                Interleave2_n(x, xOff, z, zOff, count, BitLengths[width] - 1);
 01754                break;
 1755            }
 01756        }
 1757
 1758        private static void Interleave3(long[] x, int xOff, long[] z, int zOff, int count)
 01759        {
 01760            for (int i = 0; i < count; ++i)
 01761            {
 01762                z[zOff + i] = Interleave3(x[xOff + i]);
 01763            }
 01764        }
 1765
 1766        private static long Interleave3(long x)
 01767        {
 01768            long z = x & (1L << 63);
 01769            return z
 01770                | Interleave3_21to63((int)x & 0x1FFFFF)
 01771                | Interleave3_21to63((int)((ulong)x >> 21) & 0x1FFFFF) << 1
 01772                | Interleave3_21to63((int)((ulong)x >> 42) & 0x1FFFFF) << 2;
 1773
 1774    //        int zPos = 0, wPos = 0, xPos = 0;
 1775    //        for (;;)
 1776    //        {
 1777    //            z |= ((x >>> xPos) & 1L) << zPos;
 1778    //            if (++zPos == 63)
 1779    //            {
 1780    //                String sz2 = Long.toBinaryString(z);
 1781    //                return z;
 1782    //            }
 1783    //            if ((xPos += 21) >= 63)
 1784    //            {
 1785    //                xPos = ++wPos;
 1786    //            }
 1787    //        }
 01788        }
 1789
 1790        private static long Interleave3_21to63(int x)
 01791        {
 01792            int r00 = INTERLEAVE3_TABLE[x & 0x7F];
 01793            int r21 = INTERLEAVE3_TABLE[((uint)x >> 7) & 0x7F];
 01794            int r42 = INTERLEAVE3_TABLE[(uint)x >> 14];
 01795            return (r42 & 0xFFFFFFFFL) << 42 | (r21 & 0xFFFFFFFFL) << 21 | (r00 & 0xFFFFFFFFL);
 01796        }
 1797
 1798        private static void Interleave5(long[] x, int xOff, long[] z, int zOff, int count)
 01799        {
 01800            for (int i = 0; i < count; ++i)
 01801            {
 01802                z[zOff + i] = Interleave5(x[xOff + i]);
 01803            }
 01804        }
 1805
 1806        private static long Interleave5(long x)
 01807        {
 01808            return Interleave3_13to65((int)x & 0x1FFF)
 01809                | Interleave3_13to65((int)((ulong)x >> 13) & 0x1FFF) << 1
 01810                | Interleave3_13to65((int)((ulong)x >> 26) & 0x1FFF) << 2
 01811                | Interleave3_13to65((int)((ulong)x >> 39) & 0x1FFF) << 3
 01812                | Interleave3_13to65((int)((ulong)x >> 52) & 0x1FFF) << 4;
 1813
 1814    //        long z = 0;
 1815    //        int zPos = 0, wPos = 0, xPos = 0;
 1816    //        for (;;)
 1817    //        {
 1818    //            z |= ((x >>> xPos) & 1L) << zPos;
 1819    //            if (++zPos == 64)
 1820    //            {
 1821    //                return z;
 1822    //            }
 1823    //            if ((xPos += 13) >= 64)
 1824    //            {
 1825    //                xPos = ++wPos;
 1826    //            }
 1827    //        }
 01828        }
 1829
 1830        private static long Interleave3_13to65(int x)
 01831        {
 01832            int r00 = INTERLEAVE5_TABLE[x & 0x7F];
 01833            int r35 = INTERLEAVE5_TABLE[(uint)x >> 7];
 01834            return (r35 & 0xFFFFFFFFL) << 35 | (r00 & 0xFFFFFFFFL);
 01835        }
 1836
 1837        private static void Interleave7(long[] x, int xOff, long[] z, int zOff, int count)
 01838        {
 01839            for (int i = 0; i < count; ++i)
 01840            {
 01841                z[zOff + i] = Interleave7(x[xOff + i]);
 01842            }
 01843        }
 1844
 1845        private static long Interleave7(long x)
 01846        {
 01847            long z = x & (1L << 63);
 01848            return z
 01849                | INTERLEAVE7_TABLE[(int)x & 0x1FF]
 01850                | INTERLEAVE7_TABLE[(int)((ulong)x >> 9) & 0x1FF] << 1
 01851                | INTERLEAVE7_TABLE[(int)((ulong)x >> 18) & 0x1FF] << 2
 01852                | INTERLEAVE7_TABLE[(int)((ulong)x >> 27) & 0x1FF] << 3
 01853                | INTERLEAVE7_TABLE[(int)((ulong)x >> 36) & 0x1FF] << 4
 01854                | INTERLEAVE7_TABLE[(int)((ulong)x >> 45) & 0x1FF] << 5
 01855                | INTERLEAVE7_TABLE[(int)((ulong)x >> 54) & 0x1FF] << 6;
 1856
 1857    //        int zPos = 0, wPos = 0, xPos = 0;
 1858    //        for (;;)
 1859    //        {
 1860    //            z |= ((x >>> xPos) & 1L) << zPos;
 1861    //            if (++zPos == 63)
 1862    //            {
 1863    //                return z;
 1864    //            }
 1865    //            if ((xPos += 9) >= 63)
 1866    //            {
 1867    //                xPos = ++wPos;
 1868    //            }
 1869    //        }
 01870        }
 1871
 1872        private static void Interleave2_n(long[] x, int xOff, long[] z, int zOff, int count, int rounds)
 01873        {
 01874            for (int i = 0; i < count; ++i)
 01875            {
 01876                z[zOff + i] = Interleave2_n(x[xOff + i], rounds);
 01877            }
 01878        }
 1879
 1880        private static long Interleave2_n(long x, int rounds)
 01881        {
 01882            while (rounds > 1)
 01883            {
 01884                rounds -= 2;
 01885                x = Interleave4_16to64((int)x & 0xFFFF)
 01886                    | Interleave4_16to64((int)((ulong)x >> 16) & 0xFFFF) << 1
 01887                    | Interleave4_16to64((int)((ulong)x >> 32) & 0xFFFF) << 2
 01888                    | Interleave4_16to64((int)((ulong)x >> 48) & 0xFFFF) << 3;
 01889            }
 01890            if (rounds > 0)
 01891            {
 01892                x = Interleave2_32to64((int)x) | Interleave2_32to64((int)((ulong)x >> 32)) << 1;
 01893            }
 01894            return x;
 01895        }
 1896
 1897        private static long Interleave4_16to64(int x)
 01898        {
 01899            int r00 = INTERLEAVE4_TABLE[x & 0xFF];
 01900            int r32 = INTERLEAVE4_TABLE[(uint)x >> 8];
 01901            return (r32 & 0xFFFFFFFFL) << 32 | (r00 & 0xFFFFFFFFL);
 01902        }
 1903
 1904        private static long Interleave2_32to64(int x)
 01905        {
 01906            int r00 = INTERLEAVE2_TABLE[x & 0xFF] | INTERLEAVE2_TABLE[((uint)x >> 8) & 0xFF] << 16;
 01907            int r32 = INTERLEAVE2_TABLE[((uint)x >> 16) & 0xFF] | INTERLEAVE2_TABLE[(uint)x >> 24] << 16;
 01908            return (r32 & 0xFFFFFFFFL) << 32 | (r00 & 0xFFFFFFFFL);
 01909        }
 1910
 1911    //    private static LongArray ExpItohTsujii2(LongArray B, int n, int m, int[] ks)
 1912    //    {
 1913    //        LongArray t1 = B, t3 = new LongArray(new long[]{ 1L });
 1914    //        int scale = 1;
 1915    //
 1916    //        int numTerms = n;
 1917    //        while (numTerms > 1)
 1918    //        {
 1919    //            if ((numTerms & 1) != 0)
 1920    //            {
 1921    //                t3 = t3.ModMultiply(t1, m, ks);
 1922    //                t1 = t1.modSquareN(scale, m, ks);
 1923    //            }
 1924    //
 1925    //            LongArray t2 = t1.modSquareN(scale, m, ks);
 1926    //            t1 = t1.ModMultiply(t2, m, ks);
 1927    //            numTerms >>>= 1; scale <<= 1;
 1928    //        }
 1929    //
 1930    //        return t3.ModMultiply(t1, m, ks);
 1931    //    }
 1932    //
 1933    //    private static LongArray ExpItohTsujii23(LongArray B, int n, int m, int[] ks)
 1934    //    {
 1935    //        LongArray t1 = B, t3 = new LongArray(new long[]{ 1L });
 1936    //        int scale = 1;
 1937    //
 1938    //        int numTerms = n;
 1939    //        while (numTerms > 1)
 1940    //        {
 1941    //            bool m03 = numTerms % 3 == 0;
 1942    //            bool m14 = !m03 && (numTerms & 1) != 0;
 1943    //
 1944    //            if (m14)
 1945    //            {
 1946    //                t3 = t3.ModMultiply(t1, m, ks);
 1947    //                t1 = t1.modSquareN(scale, m, ks);
 1948    //            }
 1949    //
 1950    //            LongArray t2 = t1.modSquareN(scale, m, ks);
 1951    //            t1 = t1.ModMultiply(t2, m, ks);
 1952    //
 1953    //            if (m03)
 1954    //            {
 1955    //                t2 = t2.modSquareN(scale, m, ks);
 1956    //                t1 = t1.ModMultiply(t2, m, ks);
 1957    //                numTerms /= 3; scale *= 3;
 1958    //            }
 1959    //            else
 1960    //            {
 1961    //                numTerms >>>= 1; scale <<= 1;
 1962    //            }
 1963    //        }
 1964    //
 1965    //        return t3.ModMultiply(t1, m, ks);
 1966    //    }
 1967    //
 1968    //    private static LongArray ExpItohTsujii235(LongArray B, int n, int m, int[] ks)
 1969    //    {
 1970    //        LongArray t1 = B, t4 = new LongArray(new long[]{ 1L });
 1971    //        int scale = 1;
 1972    //
 1973    //        int numTerms = n;
 1974    //        while (numTerms > 1)
 1975    //        {
 1976    //            if (numTerms % 5 == 0)
 1977    //            {
 1978    ////                t1 = ExpItohTsujii23(t1, 5, m, ks);
 1979    //
 1980    //                LongArray t3 = t1;
 1981    //                t1 = t1.modSquareN(scale, m, ks);
 1982    //
 1983    //                LongArray t2 = t1.modSquareN(scale, m, ks);
 1984    //                t1 = t1.ModMultiply(t2, m, ks);
 1985    //                t2 = t1.modSquareN(scale << 1, m, ks);
 1986    //                t1 = t1.ModMultiply(t2, m, ks);
 1987    //
 1988    //                t1 = t1.ModMultiply(t3, m, ks);
 1989    //
 1990    //                numTerms /= 5; scale *= 5;
 1991    //                continue;
 1992    //            }
 1993    //
 1994    //            bool m03 = numTerms % 3 == 0;
 1995    //            bool m14 = !m03 && (numTerms & 1) != 0;
 1996    //
 1997    //            if (m14)
 1998    //            {
 1999    //                t4 = t4.ModMultiply(t1, m, ks);
 2000    //                t1 = t1.modSquareN(scale, m, ks);
 2001    //            }
 2002    //
 2003    //            LongArray t2 = t1.modSquareN(scale, m, ks);
 2004    //            t1 = t1.ModMultiply(t2, m, ks);
 2005    //
 2006    //            if (m03)
 2007    //            {
 2008    //                t2 = t2.modSquareN(scale, m, ks);
 2009    //                t1 = t1.ModMultiply(t2, m, ks);
 2010    //                numTerms /= 3; scale *= 3;
 2011    //            }
 2012    //            else
 2013    //            {
 2014    //                numTerms >>>= 1; scale <<= 1;
 2015    //            }
 2016    //        }
 2017    //
 2018    //        return t4.ModMultiply(t1, m, ks);
 2019    //    }
 2020
 2021        public LongArray ModInverse(int m, int[] ks)
 02022        {
 2023            /*
 2024             * Fermat's Little Theorem
 2025             */
 2026    //        LongArray A = this;
 2027    //        LongArray B = A.modSquare(m, ks);
 2028    //        LongArray R0 = B, R1 = B;
 2029    //        for (int i = 2; i < m; ++i)
 2030    //        {
 2031    //            R1 = R1.modSquare(m, ks);
 2032    //            R0 = R0.ModMultiply(R1, m, ks);
 2033    //        }
 2034    //
 2035    //        return R0;
 2036
 2037            /*
 2038             * Itoh-Tsujii
 2039             */
 2040    //        LongArray B = modSquare(m, ks);
 2041    //        switch (m)
 2042    //        {
 2043    //        case 409:
 2044    //            return ExpItohTsujii23(B, m - 1, m, ks);
 2045    //        case 571:
 2046    //            return ExpItohTsujii235(B, m - 1, m, ks);
 2047    //        case 163:
 2048    //        case 233:
 2049    //        case 283:
 2050    //        default:
 2051    //            return ExpItohTsujii2(B, m - 1, m, ks);
 2052    //        }
 2053
 2054            /*
 2055             * Inversion in F2m using the extended Euclidean algorithm
 2056             *
 2057             * Input: A nonzero polynomial a(z) of degree at most m-1
 2058             * Output: a(z)^(-1) mod f(z)
 2059             */
 02060            int uzDegree = Degree();
 02061            if (uzDegree == 0)
 02062            {
 02063                throw new InvalidOperationException();
 2064            }
 02065            if (uzDegree == 1)
 02066            {
 02067                return this;
 2068            }
 2069
 2070            // u(z) := a(z)
 02071            LongArray uz = (LongArray)Copy();
 2072
 02073            int t = (m + 63) >> 6;
 2074
 2075            // v(z) := f(z)
 02076            LongArray vz = new LongArray(t);
 02077            ReduceBit(vz.m_ints, 0, m, m, ks);
 2078
 2079            // g1(z) := 1, g2(z) := 0
 02080            LongArray g1z = new LongArray(t);
 02081            g1z.m_ints[0] = 1L;
 02082            LongArray g2z = new LongArray(t);
 2083
 02084            int[] uvDeg = new int[]{ uzDegree, m + 1 };
 02085            LongArray[] uv = new LongArray[]{ uz, vz };
 2086
 02087            int[] ggDeg = new int[]{ 1, 0 };
 02088            LongArray[] gg = new LongArray[]{ g1z, g2z };
 2089
 02090            int b = 1;
 02091            int duv1 = uvDeg[b];
 02092            int dgg1 = ggDeg[b];
 02093            int j = duv1 - uvDeg[1 - b];
 2094
 2095            for (;;)
 02096            {
 02097                if (j < 0)
 02098                {
 02099                    j = -j;
 02100                    uvDeg[b] = duv1;
 02101                    ggDeg[b] = dgg1;
 02102                    b = 1 - b;
 02103                    duv1 = uvDeg[b];
 02104                    dgg1 = ggDeg[b];
 02105                }
 2106
 02107                uv[b].AddShiftedByBitsSafe(uv[1 - b], uvDeg[1 - b], j);
 2108
 02109                int duv2 = uv[b].DegreeFrom(duv1);
 02110                if (duv2 == 0)
 02111                {
 02112                    return gg[1 - b];
 2113                }
 2114
 02115                {
 02116                    int dgg2 = ggDeg[1 - b];
 02117                    gg[b].AddShiftedByBitsSafe(gg[1 - b], dgg2, j);
 02118                    dgg2 += j;
 2119
 02120                    if (dgg2 > dgg1)
 02121                    {
 02122                        dgg1 = dgg2;
 02123                    }
 02124                    else if (dgg2 == dgg1)
 02125                    {
 02126                        dgg1 = gg[b].DegreeFrom(dgg1);
 02127                    }
 02128                }
 2129
 02130                j += (duv2 - duv1);
 02131                duv1 = duv2;
 02132            }
 02133        }
 2134
 2135        public override bool Equals(object obj)
 02136        {
 02137            return Equals(obj as LongArray);
 02138        }
 2139
 2140        public virtual bool Equals(LongArray other)
 02141        {
 02142            if (this == other)
 02143                return true;
 02144            if (null == other)
 02145                return false;
 02146            int usedLen = GetUsedLength();
 02147            if (other.GetUsedLength() != usedLen)
 02148            {
 02149                return false;
 2150            }
 02151            for (int i = 0; i < usedLen; i++)
 02152            {
 02153                if (m_ints[i] != other.m_ints[i])
 02154                {
 02155                    return false;
 2156                }
 02157            }
 02158            return true;
 02159        }
 2160
 2161        public override int GetHashCode()
 02162        {
 02163            int usedLen = GetUsedLength();
 02164            int hash = 1;
 02165            for (int i = 0; i < usedLen; i++)
 02166            {
 02167                long mi = m_ints[i];
 02168                hash *= 31;
 02169                hash ^= (int)mi;
 02170                hash *= 31;
 02171                hash ^= (int)((ulong)mi >> 32);
 02172            }
 02173            return hash;
 02174        }
 2175
 2176        public LongArray Copy()
 02177        {
 02178            return new LongArray(Arrays.Clone(m_ints));
 02179        }
 2180
 2181        public override string ToString()
 02182        {
 02183            int i = GetUsedLength();
 02184            if (i == 0)
 02185            {
 02186                return "0";
 2187            }
 2188
 02189            StringBuilder sb = new StringBuilder(Convert.ToString(m_ints[--i], 2));
 02190            while (--i >= 0)
 02191            {
 02192                string s = Convert.ToString(m_ints[i], 2);
 2193
 2194                // Add leading zeroes, except for highest significant word
 02195                int len = s.Length;
 02196                if (len < 64)
 02197                {
 02198                    sb.Append(ZEROES.Substring(len));
 02199                }
 2200
 02201                sb.Append(s);
 02202            }
 02203            return sb.ToString();
 02204        }
 2205    }
 2206}

Methods/Properties

.cctor()
.ctor(System.Int32)
.ctor(System.Int64[])
.ctor(System.Int64[],System.Int32,System.Int32)
.ctor(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
CopyTo(System.Int64[],System.Int32)
IsOne()
IsZero()
GetUsedLength()
GetUsedLengthFrom(System.Int32)
Degree()
DegreeFrom(System.Int32)
BitLength(System.Int64)
ResizedInts(System.Int32)
ToBigInteger()
ShiftUp(System.Int64[],System.Int32,System.Int32,System.Int32)
ShiftUp(System.Int64[],System.Int32,System.Int64[],System.Int32,System.Int32,System.Int32)
AddOne()
AddShiftedByBitsSafe(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.LongArray,System.Int32,System.Int32)
AddShiftedUp(System.Int64[],System.Int32,System.Int64[],System.Int32,System.Int32,System.Int32)
AddShiftedDown(System.Int64[],System.Int32,System.Int64[],System.Int32,System.Int32,System.Int32)
AddShiftedByWords(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.LongArray,System.Int32)
Add(System.Int64[],System.Int32,System.Int64[],System.Int32,System.Int32)
Add(System.Int64[],System.Int32,System.Int64[],System.Int32,System.Int64[],System.Int32,System.Int32)
AddBoth(System.Int64[],System.Int32,System.Int64[],System.Int32,System.Int64[],System.Int32,System.Int32)
Distribute(System.Int64[],System.Int32,System.Int32,System.Int32,System.Int32)
get_Length()
FlipWord(System.Int64[],System.Int32,System.Int32,System.Int64)
TestBitZero()
TestBit(System.Int64[],System.Int32,System.Int32)
FlipBit(System.Int64[],System.Int32,System.Int32)
MultiplyWord(System.Int64,System.Int64[],System.Int32,System.Int64[],System.Int32)
ModMultiplyLD(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.LongArray,System.Int32,System.Int32[])
ModMultiply(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.LongArray,System.Int32,System.Int32[])
ModMultiplyAlt(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.LongArray,System.Int32,System.Int32[])
ModReduce(System.Int32,System.Int32[])
Multiply(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.LongArray,System.Int32,System.Int32[])
Reduce(System.Int32,System.Int32[])
ReduceResult(System.Int64[],System.Int32,System.Int32,System.Int32,System.Int32[])
ReduceInPlace(System.Int64[],System.Int32,System.Int32,System.Int32,System.Int32[])
ReduceBitWise(System.Int64[],System.Int32,System.Int32,System.Int32,System.Int32[])
ReduceBit(System.Int64[],System.Int32,System.Int32,System.Int32,System.Int32[])
ReduceWordWise(System.Int64[],System.Int32,System.Int32,System.Int32,System.Int32,System.Int32[])
ReduceWord(System.Int64[],System.Int32,System.Int32,System.Int64,System.Int32,System.Int32[])
ReduceVectorWise(System.Int64[],System.Int32,System.Int32,System.Int32,System.Int32,System.Int32[])
FlipVector(System.Int64[],System.Int32,System.Int64[],System.Int32,System.Int32,System.Int32)
ModSquare(System.Int32,System.Int32[])
ModSquareN(System.Int32,System.Int32,System.Int32[])
Square(System.Int32,System.Int32[])
SquareInPlace(System.Int64[],System.Int32,System.Int32,System.Int32[])
Interleave(System.Int64[],System.Int32,System.Int64[],System.Int32,System.Int32,System.Int32)
Interleave3(System.Int64[],System.Int32,System.Int64[],System.Int32,System.Int32)
Interleave3(System.Int64)
Interleave3_21to63(System.Int32)
Interleave5(System.Int64[],System.Int32,System.Int64[],System.Int32,System.Int32)
Interleave5(System.Int64)
Interleave3_13to65(System.Int32)
Interleave7(System.Int64[],System.Int32,System.Int64[],System.Int32,System.Int32)
Interleave7(System.Int64)
Interleave2_n(System.Int64[],System.Int32,System.Int64[],System.Int32,System.Int32,System.Int32)
Interleave2_n(System.Int64,System.Int32)
Interleave4_16to64(System.Int32)
Interleave2_32to64(System.Int32)
ModInverse(System.Int32,System.Int32[])
Equals(System.Object)
Equals(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.LongArray)
GetHashCode()
Copy()
ToString()