private static int[] Square(
int[] w,
int[] x)
{
// Note: this method allows w to be only (2 * x.Length - 1) words if result will fit
// if (w.Length != 2 * x.Length)
// throw new ArgumentException("no I don't think so...");
ulong u1, u2, c;
int wBase = w.Length - 1;
for (int i = x.Length - 1; i != 0; i--)
{
ulong v = (ulong)(uint) x[i];
u1 = v * v;
u2 = u1 >> 32;
u1 = (uint) u1;
u1 += (ulong)(uint) w[wBase];
w[wBase] = (int)(uint) u1;
c = u2 + (u1 >> 32);
for (int j = i - 1; j >= 0; j--)
{
--wBase;
u1 = v * (ulong)(uint) x[j];
u2 = u1 >> 31; // multiply by 2!
u1 = (uint)(u1 << 1); // multiply by 2!
u1 += c + (ulong)(uint) w[wBase];
w[wBase] = (int)(uint) u1;
c = u2 + (u1 >> 32);
}
c += (ulong)(uint) w[--wBase];
w[wBase] = (int)(uint) c;
if (--wBase >= 0)
{
w[wBase] = (int)(uint)(c >> 32);
}
else
{
Debug.Assert((uint)(c >> 32) == 0);
}
wBase += i;
}
u1 = (ulong)(uint) x[0];
u1 = u1 * u1;
u2 = u1 >> 32;
u1 = u1 & IMASK;
u1 += (ulong)(uint) w[wBase];
w[wBase] = (int)(uint) u1;
if (--wBase >= 0)
{
w[wBase] = (int)(uint)(u2 + (u1 >> 32) + (ulong)(uint) w[wBase]);
}
else
{
Debug.Assert((uint)(u2 + (u1 >> 32)) == 0);
}
return w;
}