HrssPolynomial
using Org.BouncyCastle.Pqc.Crypto.Ntru.ParameterSets;
namespace Org.BouncyCastle.Pqc.Crypto.Ntru.Polynomials
{
internal class HrssPolynomial : Polynomial
{
internal HrssPolynomial(NtruParameterSet parameterSet)
: base(parameterSet)
{
}
public override byte[] SqToBytes(int len)
{
byte[] array = new byte[len];
short[] array2 = new short[8];
int i;
int j;
for (i = 0; i < ParameterSet.PackDegree() / 8; i++) {
for (j = 0; j < 8; j++) {
array2[j] = (short)Polynomial.ModQ((uint)(coeffs[8 * i + j] & 65535), (uint)ParameterSet.Q());
}
array[13 * i] = (byte)(array2[0] & 255);
array[13 * i + 1] = (byte)((array2[0] >> 8) | ((array2[1] & 7) << 5));
array[13 * i + 2] = (byte)((array2[1] >> 3) & 255);
array[13 * i + 3] = (byte)((array2[1] >> 11) | ((array2[2] & 63) << 2));
array[13 * i + 4] = (byte)((array2[2] >> 6) | ((array2[3] & 1) << 7));
array[13 * i + 5] = (byte)((array2[3] >> 1) & 255);
array[13 * i + 6] = (byte)((array2[3] >> 9) | ((array2[4] & 15) << 4));
array[13 * i + 7] = (byte)((array2[4] >> 4) & 255);
array[13 * i + 8] = (byte)((array2[4] >> 12) | ((array2[5] & 127) << 1));
array[13 * i + 9] = (byte)((array2[5] >> 7) | ((array2[6] & 3) << 6));
array[13 * i + 10] = (byte)((array2[6] >> 2) & 255);
array[13 * i + 11] = (byte)((array2[6] >> 10) | ((array2[7] & 31) << 3));
array[13 * i + 12] = (byte)(array2[7] >> 5);
}
for (j = 0; j < ParameterSet.PackDegree() - 8 * i; j++) {
array2[j] = (short)Polynomial.ModQ((uint)(coeffs[8 * i + j] & 65535), (uint)ParameterSet.Q());
}
for (; j < 8; j++) {
array2[j] = 0;
}
switch (ParameterSet.PackDegree() - 8 * (ParameterSet.PackDegree() / 8)) {
case 4:
array[13 * i] = (byte)(array2[0] & 255);
array[13 * i + 1] = (byte)((array2[0] >> 8) | ((array2[1] & 7) << 5));
array[13 * i + 2] = (byte)((array2[1] >> 3) & 255);
array[13 * i + 3] = (byte)((array2[1] >> 11) | ((array2[2] & 63) << 2));
array[13 * i + 4] = (byte)((array2[2] >> 6) | ((array2[3] & 1) << 7));
array[13 * i + 5] = (byte)((array2[3] >> 1) & 255);
array[13 * i + 6] = (byte)((array2[3] >> 9) | ((array2[4] & 15) << 4));
break;
case 2:
array[13 * i] = (byte)(array2[0] & 255);
array[13 * i + 1] = (byte)((array2[0] >> 8) | ((array2[1] & 7) << 5));
array[13 * i + 2] = (byte)((array2[1] >> 3) & 255);
array[13 * i + 3] = (byte)((array2[1] >> 11) | ((array2[2] & 63) << 2));
break;
}
return array;
}
public override void SqFromBytes(byte[] a)
{
int i;
for (i = 0; i < ParameterSet.PackDegree() / 8; i++) {
coeffs[8 * i] = (ushort)((a[13 * i] & 255) | (((ushort)(a[13 * i + 1] & 255) & 31) << 8));
coeffs[8 * i + 1] = (ushort)(((a[13 * i + 1] & 255) >> 5) | ((ushort)(a[13 * i + 2] & 255) << 3) | (((short)(a[13 * i + 3] & 255) & 3) << 11));
coeffs[8 * i + 2] = (ushort)(((a[13 * i + 3] & 255) >> 2) | (((ushort)(a[13 * i + 4] & 255) & 127) << 6));
coeffs[8 * i + 3] = (ushort)(((a[13 * i + 4] & 255) >> 7) | ((ushort)(a[13 * i + 5] & 255) << 1) | (((short)(a[13 * i + 6] & 255) & 15) << 9));
coeffs[8 * i + 4] = (ushort)(((a[13 * i + 6] & 255) >> 4) | ((ushort)(a[13 * i + 7] & 255) << 4) | (((short)(a[13 * i + 8] & 255) & 1) << 12));
coeffs[8 * i + 5] = (ushort)(((a[13 * i + 8] & 255) >> 1) | (((ushort)(a[13 * i + 9] & 255) & 63) << 7));
coeffs[8 * i + 6] = (ushort)(((a[13 * i + 9] & 255) >> 6) | ((ushort)(a[13 * i + 10] & 255) << 2) | (((short)(a[13 * i + 11] & 255) & 7) << 10));
coeffs[8 * i + 7] = (ushort)(((a[13 * i + 11] & 255) >> 3) | ((ushort)(a[13 * i + 12] & 255) << 5));
}
switch (ParameterSet.PackDegree() & 7) {
case 4:
coeffs[8 * i] = (ushort)((a[13 * i] & 255) | (((short)(a[13 * i + 1] & 255) & 31) << 8));
coeffs[8 * i + 1] = (ushort)(((a[13 * i + 1] & 255) >> 5) | ((short)(a[13 * i + 2] & 255) << 3) | (((short)(a[13 * i + 3] & 255) & 3) << 11));
coeffs[8 * i + 2] = (ushort)(((a[13 * i + 3] & 255) >> 2) | (((short)(a[13 * i + 4] & 255) & 127) << 6));
coeffs[8 * i + 3] = (ushort)(((a[13 * i + 4] & 255) >> 7) | ((short)(a[13 * i + 5] & 255) << 1) | (((short)(a[13 * i + 6] & 255) & 15) << 9));
break;
case 2:
coeffs[8 * i] = (ushort)((a[13 * i] & 255) | (((short)(a[13 * i + 1] & 255) & 31) << 8));
coeffs[8 * i + 1] = (ushort)(((a[13 * i + 1] & 255) >> 5) | ((short)(a[13 * i + 2] & 255) << 3) | (((short)(a[13 * i + 3] & 255) & 3) << 11));
break;
}
coeffs[ParameterSet.N - 1] = 0;
}
public override void Lift(Polynomial a)
{
int num = base.coeffs.Length;
HrssPolynomial hrssPolynomial = new HrssPolynomial((NtruHrssParameterSet)ParameterSet);
ushort num2 = (ushort)(3 - num % 3);
ushort[] coeffs = hrssPolynomial.coeffs;
int num3 = a.coeffs[0] * (2 - num2);
ushort num6 = a.coeffs[1];
coeffs[0] = (ushort)(num3 + 0 + a.coeffs[2] * num2);
ushort[] coeffs2 = hrssPolynomial.coeffs;
int num4 = a.coeffs[1] * (2 - num2);
ushort num7 = a.coeffs[2];
coeffs2[1] = (ushort)(num4 + 0);
hrssPolynomial.coeffs[2] = (ushort)(a.coeffs[2] * (2 - num2));
ushort num5 = 0;
for (int i = 3; i < num; i++) {
hrssPolynomial.coeffs[0] += (ushort)(a.coeffs[i] * (num5 + 2 * num2));
hrssPolynomial.coeffs[1] += (ushort)(a.coeffs[i] * (num5 + num2));
hrssPolynomial.coeffs[2] += (ushort)(a.coeffs[i] * num5);
num5 = (ushort)((num5 + num2) % 3);
}
hrssPolynomial.coeffs[1] += (ushort)(a.coeffs[0] * (num5 + num2));
hrssPolynomial.coeffs[2] += (ushort)(a.coeffs[0] * num5);
hrssPolynomial.coeffs[2] += (ushort)(a.coeffs[1] * (num5 + num2));
for (int i = 3; i < num; i++) {
hrssPolynomial.coeffs[i] = (ushort)(hrssPolynomial.coeffs[i - 3] + 2 * (a.coeffs[i] + a.coeffs[i - 1] + a.coeffs[i - 2]));
}
hrssPolynomial.Mod3PhiN();
hrssPolynomial.Z3ToZq();
base.coeffs[0] = (ushort)(-hrssPolynomial.coeffs[0]);
for (int i = 0; i < num - 1; i++) {
base.coeffs[i + 1] = (ushort)(hrssPolynomial.coeffs[i] - hrssPolynomial.coeffs[i + 1]);
}
}
public override void R2Inv(Polynomial a)
{
HrssPolynomial f = new HrssPolynomial((NtruHrssParameterSet)ParameterSet);
HrssPolynomial g = new HrssPolynomial((NtruHrssParameterSet)ParameterSet);
HrssPolynomial v = new HrssPolynomial((NtruHrssParameterSet)ParameterSet);
HrssPolynomial w = new HrssPolynomial((NtruHrssParameterSet)ParameterSet);
R2Inv(a, f, g, v, w);
}
public override void RqInv(Polynomial a)
{
HrssPolynomial ai = new HrssPolynomial((NtruHrssParameterSet)ParameterSet);
HrssPolynomial b = new HrssPolynomial((NtruHrssParameterSet)ParameterSet);
HrssPolynomial c = new HrssPolynomial((NtruHrssParameterSet)ParameterSet);
HrssPolynomial s = new HrssPolynomial((NtruHrssParameterSet)ParameterSet);
RqInv(a, ai, b, c, s);
}
public override void S3Inv(Polynomial a)
{
HrssPolynomial f = new HrssPolynomial((NtruHrssParameterSet)ParameterSet);
HrssPolynomial g = new HrssPolynomial((NtruHrssParameterSet)ParameterSet);
HrssPolynomial v = new HrssPolynomial((NtruHrssParameterSet)ParameterSet);
HrssPolynomial w = new HrssPolynomial((NtruHrssParameterSet)ParameterSet);
S3Inv(a, f, g, v, w);
}
}
}