summary refs log tree commit diff
path: root/crypto/src/pqc/crypto/cmce/GF.cs
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-11-16 22:33:55 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-11-16 22:33:55 +0700
commitb72cba6a65e5a4de6edc8865bdb25acc00c48e8c (patch)
tree6a02fd7b6d4c9c70d4a652caaec50aa77a12a69a /crypto/src/pqc/crypto/cmce/GF.cs
parentMerge branch 'release/v2.0' (diff)
downloadBouncyCastle.NET-ed25519-b72cba6a65e5a4de6edc8865bdb25acc00c48e8c.tar.xz
Refactoring in Pqc.Crypto.Cmce
Diffstat (limited to '')
-rw-r--r--crypto/src/pqc/crypto/cmce/GF.cs172
1 files changed, 154 insertions, 18 deletions
diff --git a/crypto/src/pqc/crypto/cmce/GF.cs b/crypto/src/pqc/crypto/cmce/GF.cs
index 2892278e0..8c5123107 100644
--- a/crypto/src/pqc/crypto/cmce/GF.cs
+++ b/crypto/src/pqc/crypto/cmce/GF.cs
@@ -1,4 +1,3 @@
-using System;
 using System.Diagnostics;
 
 using Org.BouncyCastle.Math.Raw;
@@ -7,8 +6,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 {
     internal interface GF
     {
-        ushort GFAdd(ushort left, ushort right);
-        uint GFAddExt(uint left, uint right);
+        void GFMulPoly(int length, int[] poly, ushort[] output, ushort[] left, ushort[] right, uint[] temp);
+        void GFSqrPoly(int length, int[] poly, ushort[] output, ushort[] input, uint[] temp);
+
         ushort GFFrac(ushort den, ushort num);
         ushort GFInv(ushort input);
         ushort GFIsZero(ushort a);
@@ -22,14 +22,71 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
     internal struct GF12
         : GF
     {
-        public ushort GFAdd(ushort left, ushort right)
+        public void GFMulPoly(int length, int[] poly, ushort[] output, ushort[] left, ushort[] right, uint[] temp)
         {
-            return (ushort)(left ^ right);
+            temp[0] = GFMulExt(left[0], right[0]);
+
+            for (int i = 1; i < length; i++)
+            {
+                temp[i + i - 1] = 0U;
+
+                ushort left_i = left[i];
+                ushort right_i = right[i];
+
+                for (int j = 0; j < i; j++)
+                {
+                    temp[i + j] ^= GFMulExtPar(left_i, right[j], left[j], right_i);
+                }
+
+                temp[i + i] = GFMulExt(left_i, right_i);
+            }
+
+            for (int i = (length - 1) * 2; i >= length; i--)
+            {
+                uint temp_i = temp[i];
+
+                for (int j = 0; j < poly.Length - 1; j++)
+                {
+                    temp[i - length + poly[j]] ^= temp_i;
+                }
+                {
+                    temp[i - length] ^= GFMulExt(GFReduce(temp_i), 2);
+                }
+            }
+
+            for (int i = 0; i < length; ++i)
+            {
+                output[i] = GFReduce(temp[i]);
+            }
         }
 
-        public uint GFAddExt(uint left, uint right)
+        public void GFSqrPoly(int length, int[] poly, ushort[] output, ushort[] input, uint[] temp)
         {
-            return left ^ right;
+            temp[0] = GFSqExt(input[0]);
+
+            for (int i = 1; i < length; i++)
+            {
+                temp[i + i - 1] = 0;
+                temp[i + i] = GFSqExt(input[i]);
+            }
+
+            for (int i = (length - 1) * 2; i >= length; i--)
+            {
+                uint temp_i = temp[i];
+
+                for (int j = 0; j < poly.Length - 1; j++)
+                {
+                    temp[i - length + poly[j]] ^= temp_i;
+                }
+                {
+                    temp[i - length] ^= GFMulExt(GFReduce(temp_i), 2);
+                }
+            }
+
+            for (int i = 0; i < length; ++i)
+            {
+                output[i] = GFReduce(temp[i]);
+            }
         }
 
         public ushort GFFrac(ushort den, ushort num)
@@ -88,8 +145,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 
         public uint GFMulExt(ushort left, ushort right)
         {
-            int x = left;
-            int y = right;
+            int x = left, y = right;
 
             int z = x * (y & 1);
             for (int i = 1; i < 12; i++)
@@ -100,6 +156,22 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
             return (uint)z;
         }
 
+        private uint GFMulExtPar(ushort left0, ushort right0, ushort left1, ushort right1)
+        {
+            int x0 = left0, y0 = right0, x1 = left1, y1 = right1;
+
+            int z0 = x0 * (y0 & 1);
+            int z1 = x1 * (y1 & 1);
+
+            for (int i = 1; i < 12; i++)
+            {
+                z0 ^= x0 * (y0 & (1 << i));
+                z1 ^= x1 * (y1 & (1 << i));
+            }
+
+            return (uint)(z0 ^ z1);
+        }
+
         public ushort GFReduce(uint x)
         {
             Debug.Assert((x >> 24) == 0);
@@ -128,16 +200,65 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
     internal struct GF13
         : GF
     {
-        private const int GFMASK = (1 << 13) - 1;
-
-        public ushort GFAdd(ushort left, ushort right)
+        public void GFMulPoly(int length, int[] poly, ushort[] output, ushort[] left, ushort[] right, uint[] temp)
         {
-            return (ushort)(left ^ right);
+            temp[0] = GFMulExt(left[0], right[0]);
+
+            for (int i = 1; i < length; i++)
+            {
+                temp[i + i - 1] = 0U;
+
+                ushort left_i = left[i];
+                ushort right_i = right[i];
+
+                for (int j = 0; j < i; j++)
+                {
+                    temp[i + j] ^= GFMulExtPar(left_i, right[j], left[j], right_i);
+                }
+
+                temp[i + i] = GFMulExt(left_i, right_i);
+            }
+
+            for (int i = (length - 1) * 2; i >= length; i--)
+            {
+                uint temp_i = temp[i];
+
+                for (int j = 0; j < poly.Length; j++)
+                {
+                    temp[i - length + poly[j]] ^= temp_i;
+                }
+            }
+
+            for (int i = 0; i < length; ++i)
+            {
+                output[i] = GFReduce(temp[i]);
+            }
         }
 
-        public uint GFAddExt(uint left, uint right)
+        public void GFSqrPoly(int length, int[] poly, ushort[] output, ushort[] input, uint[] temp)
         {
-            return left ^ right;
+            temp[0] = GFSqExt(input[0]);
+
+            for (int i = 1; i < length; i++)
+            {
+                temp[i + i - 1] = 0;
+                temp[i + i] = GFSqExt(input[i]);
+            }
+
+            for (int i = (length - 1) * 2; i >= length; i--)
+            {
+                uint temp_i = temp[i];
+
+                for (int j = 0; j < poly.Length; j++)
+                {
+                    temp[i - length + poly[j]] ^= temp_i;
+                }
+            }
+
+            for (int i = 0; i < length; ++i)
+            {
+                output[i] = GFReduce(temp[i]);
+            }
         }
 
         /* input: field element den, num */
@@ -180,10 +301,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
             return GFReduce((uint)z);
         }
 
-        public uint GFMulExt(ushort in0, ushort in1)
+        public uint GFMulExt(ushort left, ushort right)
         {
-            int x = in0;
-            int y = in1;
+            int x = left, y = right;
 
             int z = x * (y & 1);
             for (int i = 1; i < 13; i++)
@@ -194,6 +314,22 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
             return (uint)z;
         }
 
+        private uint GFMulExtPar(ushort left0, ushort right0, ushort left1, ushort right1)
+        {
+            int x0 = left0, y0 = right0, x1 = left1, y1 = right1;
+
+            int z0 = x0 * (y0 & 1);
+            int z1 = x1 * (y1 & 1);
+
+            for (int i = 1; i < 13; i++)
+            {
+                z0 ^= x0 * (y0 & (1 << i));
+                z1 ^= x1 * (y1 & (1 << i));
+            }
+
+            return (uint)(z0 ^ z1);
+        }
+
         public ushort GFReduce(uint x)
         {
             Debug.Assert((x >> 26) == 0);