summary refs log tree commit diff
path: root/crypto/src/pqc/crypto/ntru/polynomials/HpsPolynomial.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/pqc/crypto/ntru/polynomials/HpsPolynomial.cs')
-rw-r--r--crypto/src/pqc/crypto/ntru/polynomials/HpsPolynomial.cs162
1 files changed, 162 insertions, 0 deletions
diff --git a/crypto/src/pqc/crypto/ntru/polynomials/HpsPolynomial.cs b/crypto/src/pqc/crypto/ntru/polynomials/HpsPolynomial.cs
new file mode 100644
index 000000000..6097912a1
--- /dev/null
+++ b/crypto/src/pqc/crypto/ntru/polynomials/HpsPolynomial.cs
@@ -0,0 +1,162 @@
+using System;
+using Org.BouncyCastle.Pqc.Crypto.Ntru.ParameterSets;
+
+namespace Org.BouncyCastle.Pqc.Crypto.Ntru.Polynomials
+{
+    internal class HpsPolynomial : Polynomial
+    {
+        public HpsPolynomial(NtruParameterSet parameterSet) : base(parameterSet)
+        {
+        }
+
+        public override byte[] SqToBytes(int len)
+        {
+            byte[] r = new byte[len];
+
+            int i, j;
+            short[] t = new short[8];
+            for (i = 0;
+                 i < ParameterSet.PackDegree() / 8;
+                 i++)
+            {
+                for (j = 0; j < 8; j++)
+                {
+                    t[j] = (short)ModQ((uint)coeffs[8 * i + j] & 0xffff, (uint)ParameterSet.Q());
+                }
+
+                r[11 * i + 0] = (byte)(t[0] & 0xff);
+                r[11 * i + 1] = (byte)((t[0] >> 8) | ((t[1] & 0x1f) << 3));
+                r[11 * i + 2] = (byte)((t[1] >> 5) | ((t[2] & 0x03) << 6));
+                r[11 * i + 3] = (byte)((t[2] >> 2) & 0xff);
+                r[11 * i + 4] = (byte)((t[2] >> 10) | ((t[3] & 0x7f) << 1));
+                r[11 * i + 5] = (byte)((t[3] >> 7) | ((t[4] & 0x0f) << 4));
+                r[11 * i + 6] = (byte)((t[4] >> 4) | ((t[5] & 0x01) << 7));
+                r[11 * i + 7] = (byte)((t[5] >> 1) & 0xff);
+                r[11 * i + 8] = (byte)((t[5] >> 9) | ((t[6] & 0x3f) << 2));
+                r[11 * i + 9] = (byte)((t[6] >> 6) | ((t[7] & 0x07) << 5));
+                r[11 * i + 10] = (byte)(t[7] >> 3);
+            }
+
+            for (j = 0; j < ParameterSet.PackDegree() - 8 * i; j++)
+            {
+                t[j] = (short)ModQ((uint)coeffs[8 * i + j] & 0xffff, (uint)ParameterSet.Q());
+            }
+
+            for (; j < 8; j++)
+            {
+                t[j] = 0;
+            }
+
+            switch (ParameterSet.PackDegree() & 0x07)
+            {
+                case 4:
+                {
+                    r[11 * i + 0] = (byte)(t[0] & 0xff);
+                    r[11 * i + 1] = (byte)((t[0] >> 8) | ((t[1] & 0x1f) << 3));
+                    r[11 * i + 2] = (byte)((t[1] >> 5) | ((t[2] & 0x03) << 6));
+                    r[11 * i + 3] = (byte)((t[2] >> 2) & 0xff);
+                    r[11 * i + 4] = (byte)((t[2] >> 10) | ((t[3] & 0x7f) << 1));
+                    r[11 * i + 5] = (byte)((t[3] >> 7) | ((t[4] & 0x0f) << 4));
+                    break;
+                }
+                case 2:
+                {
+                    r[11 * i + 0] = (byte)(t[0] & 0xff);
+                    r[11 * i + 1] = (byte)((t[0] >> 8) | ((t[1] & 0x1f) << 3));
+                    r[11 * i + 2] = (byte)((t[1] >> 5) | ((t[2] & 0x03) << 6));
+                    break;
+                }
+            }
+
+            return r;
+        }
+
+        public override void SqFromBytes(byte[] a)
+        {
+            int n = coeffs.Length;
+            int i;
+            for (i = 0; i < ParameterSet.PackDegree() / 8; i++)
+            {
+                coeffs[8 * i + 0] =
+                    (ushort)(((a[11 * i + 0] & 0xff) >> 0) | (((ushort)(a[11 * i + 1] & 0xff) & 0x07) << 8));
+                coeffs[8 * i + 1] =
+                    (ushort)(((a[11 * i + 1] & 0xff) >> 3) | (((ushort)(a[11 * i + 2] & 0xff) & 0x3f) << 5));
+                coeffs[8 * i + 2] = (ushort)(((a[11 * i + 2] & 0xff) >> 6) |
+                                             (((ushort)(a[11 * i + 3] & 0xff) & 0xff) << 2) |
+                                             (((ushort)(a[11 * i + 4] & 0xff) & 0x01) << 10));
+                coeffs[8 * i + 3] =
+                    (ushort)(((a[11 * i + 4] & 0xff) >> 1) | (((ushort)(a[11 * i + 5] & 0xff) & 0x0f) << 7));
+                coeffs[8 * i + 4] =
+                    (ushort)(((a[11 * i + 5] & 0xff) >> 4) | (((ushort)(a[11 * i + 6] & 0xff) & 0x7f) << 4));
+                coeffs[8 * i + 5] = (ushort)(((a[11 * i + 6] & 0xff) >> 7) |
+                                             (((ushort)(a[11 * i + 7] & 0xff) & 0xff) << 1) |
+                                             (((ushort)(a[11 * i + 8] & 0xff) & 0x03) << 9));
+                coeffs[8 * i + 6] =
+                    (ushort)(((a[11 * i + 8] & 0xff) >> 2) | (((ushort)(a[11 * i + 9] & 0xff) & 0x1f) << 6));
+                coeffs[8 * i + 7] =
+                    (ushort)(((a[11 * i + 9] & 0xff) >> 5) | (((ushort)(a[11 * i + 10] & 0xff) & 0xff) << 3));
+            }
+
+            switch (ParameterSet.PackDegree() & 0x07)
+            {
+                case 4:
+                {
+                    coeffs[8 * i + 0] =
+                        (ushort)(((a[11 * i + 0] & 0xff) >> 0) | (((ushort)(a[11 * i + 1] & 0xff) & 0x07) << 8));
+                    coeffs[8 * i + 1] =
+                        (ushort)(((a[11 * i + 1] & 0xff) >> 3) | (((ushort)(a[11 * i + 2] & 0xff) & 0x3f) << 5));
+                    coeffs[8 * i + 2] = (ushort)(((a[11 * i + 2] & 0xff) >> 6) |
+                                                 (((ushort)(a[11 * i + 3] & 0xff) & 0xff) << 2) |
+                                                 (((ushort)(a[11 * i + 4] & 0xff) & 0x01) << 10));
+                    coeffs[8 * i + 3] =
+                        (ushort)(((a[11 * i + 4] & 0xff) >> 1) | (((ushort)(a[11 * i + 5] & 0xff) & 0x0f) << 7));
+                    break;
+                }
+                case 2:
+                {
+                    coeffs[8 * i + 0] =
+                        (ushort)(((a[11 * i + 0] & 0xff) >> 0) | (((ushort)(a[11 * i + 1] & 0xff) & 0x07) << 8));
+                    coeffs[8 * i + 1] =
+                        (ushort)(((a[11 * i + 1] & 0xff) >> 3) | (((ushort)(a[11 * i + 2] & 0xff) & 0x3f) << 5));
+                    break;
+                }
+            }
+
+            coeffs[n - 1] = 0;
+        }
+
+        public override void Lift(Polynomial a)
+        {
+            int n = coeffs.Length;
+            Array.Copy(a.coeffs, 0, coeffs, 0, n);
+            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 ai2 = new HpsPolynomial((NtruHpsParameterSet)ParameterSet);
+            HpsPolynomial b = new HpsPolynomial((NtruHpsParameterSet)ParameterSet);
+            HpsPolynomial c = new HpsPolynomial((NtruHpsParameterSet)ParameterSet);
+            HpsPolynomial s = new HpsPolynomial((NtruHpsParameterSet)ParameterSet);
+            RqInv(a, ai2, 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);
+        }
+    }
+}
\ No newline at end of file