<PackageReference Include="BouncyCastle.Cryptography" Version="2.3.1" />

HpsPolynomial

using Org.BouncyCastle.Pqc.Crypto.Ntru.ParameterSets; using System; namespace Org.BouncyCastle.Pqc.Crypto.Ntru.Polynomials { internal class HpsPolynomial : Polynomial { internal HpsPolynomial(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[11 * i] = (byte)(array2[0] & 255); array[11 * i + 1] = (byte)((array2[0] >> 8) | ((array2[1] & 31) << 3)); array[11 * i + 2] = (byte)((array2[1] >> 5) | ((array2[2] & 3) << 6)); array[11 * i + 3] = (byte)((array2[2] >> 2) & 255); array[11 * i + 4] = (byte)((array2[2] >> 10) | ((array2[3] & 127) << 1)); array[11 * i + 5] = (byte)((array2[3] >> 7) | ((array2[4] & 15) << 4)); array[11 * i + 6] = (byte)((array2[4] >> 4) | ((array2[5] & 1) << 7)); array[11 * i + 7] = (byte)((array2[5] >> 1) & 255); array[11 * i + 8] = (byte)((array2[5] >> 9) | ((array2[6] & 63) << 2)); array[11 * i + 9] = (byte)((array2[6] >> 6) | ((array2[7] & 7) << 5)); array[11 * i + 10] = (byte)(array2[7] >> 3); } 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() & 7) { case 4: array[11 * i] = (byte)(array2[0] & 255); array[11 * i + 1] = (byte)((array2[0] >> 8) | ((array2[1] & 31) << 3)); array[11 * i + 2] = (byte)((array2[1] >> 5) | ((array2[2] & 3) << 6)); array[11 * i + 3] = (byte)((array2[2] >> 2) & 255); array[11 * i + 4] = (byte)((array2[2] >> 10) | ((array2[3] & 127) << 1)); array[11 * i + 5] = (byte)((array2[3] >> 7) | ((array2[4] & 15) << 4)); break; case 2: array[11 * i] = (byte)(array2[0] & 255); array[11 * i + 1] = (byte)((array2[0] >> 8) | ((array2[1] & 31) << 3)); array[11 * i + 2] = (byte)((array2[1] >> 5) | ((array2[2] & 3) << 6)); break; } return array; } public override void SqFromBytes(byte[] a) { int num = coeffs.Length; int i; for (i = 0; i < ParameterSet.PackDegree() / 8; i++) { coeffs[8 * i] = (ushort)((a[11 * i] & 255) | (((ushort)(a[11 * i + 1] & 255) & 7) << 8)); coeffs[8 * i + 1] = (ushort)(((a[11 * i + 1] & 255) >> 3) | (((ushort)(a[11 * i + 2] & 255) & 63) << 5)); coeffs[8 * i + 2] = (ushort)(((a[11 * i + 2] & 255) >> 6) | (((ushort)(a[11 * i + 3] & 255) & 255) << 2) | (((ushort)(a[11 * i + 4] & 255) & 1) << 10)); coeffs[8 * i + 3] = (ushort)(((a[11 * i + 4] & 255) >> 1) | (((ushort)(a[11 * i + 5] & 255) & 15) << 7)); coeffs[8 * i + 4] = (ushort)(((a[11 * i + 5] & 255) >> 4) | (((ushort)(a[11 * i + 6] & 255) & 127) << 4)); coeffs[8 * i + 5] = (ushort)(((a[11 * i + 6] & 255) >> 7) | (((ushort)(a[11 * i + 7] & 255) & 255) << 1) | (((ushort)(a[11 * i + 8] & 255) & 3) << 9)); coeffs[8 * i + 6] = (ushort)(((a[11 * i + 8] & 255) >> 2) | (((ushort)(a[11 * i + 9] & 255) & 31) << 6)); coeffs[8 * i + 7] = (ushort)(((a[11 * i + 9] & 255) >> 5) | (((ushort)(a[11 * i + 10] & 255) & 255) << 3)); } switch (ParameterSet.PackDegree() & 7) { case 4: coeffs[8 * i] = (ushort)((a[11 * i] & 255) | (((ushort)(a[11 * i + 1] & 255) & 7) << 8)); coeffs[8 * i + 1] = (ushort)(((a[11 * i + 1] & 255) >> 3) | (((ushort)(a[11 * i + 2] & 255) & 63) << 5)); coeffs[8 * i + 2] = (ushort)(((a[11 * i + 2] & 255) >> 6) | (((ushort)(a[11 * i + 3] & 255) & 255) << 2) | (((ushort)(a[11 * i + 4] & 255) & 1) << 10)); coeffs[8 * i + 3] = (ushort)(((a[11 * i + 4] & 255) >> 1) | (((ushort)(a[11 * i + 5] & 255) & 15) << 7)); break; case 2: coeffs[8 * i] = (ushort)((a[11 * i] & 255) | (((ushort)(a[11 * i + 1] & 255) & 7) << 8)); coeffs[8 * i + 1] = (ushort)(((a[11 * i + 1] & 255) >> 3) | (((ushort)(a[11 * i + 2] & 255) & 63) << 5)); break; } coeffs[num - 1] = 0; } public override void Lift(Polynomial a) { int length = coeffs.Length; Array.Copy(a.coeffs, 0, coeffs, 0, length); Z3ToZq(); } public override void R2Inv(Polynomial a) { HpsPolynomial f = new HpsPolynomial((NtruHpsParameterSet)ParameterSet); HpsPolynomial g = new HpsPolynomial((NtruHpsParameterSet)ParameterSet); HpsPolynomial v = new HpsPolynomial((NtruHpsParameterSet)ParameterSet); HpsPolynomial w = new HpsPolynomial((NtruHpsParameterSet)ParameterSet); R2Inv(a, f, g, v, w); } public override void RqInv(Polynomial a) { HpsPolynomial ai = new HpsPolynomial((NtruHpsParameterSet)ParameterSet); HpsPolynomial b = new HpsPolynomial((NtruHpsParameterSet)ParameterSet); HpsPolynomial c = new HpsPolynomial((NtruHpsParameterSet)ParameterSet); HpsPolynomial s = new HpsPolynomial((NtruHpsParameterSet)ParameterSet); RqInv(a, ai, b, c, s); } public override void S3Inv(Polynomial a) { HpsPolynomial f = new HpsPolynomial((NtruHpsParameterSet)ParameterSet); HpsPolynomial g = new HpsPolynomial((NtruHpsParameterSet)ParameterSet); HpsPolynomial v = new HpsPolynomial((NtruHpsParameterSet)ParameterSet); HpsPolynomial w = new HpsPolynomial((NtruHpsParameterSet)ParameterSet); S3Inv(a, f, g, v, w); } } }