summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-11-13 00:06:54 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-11-13 00:06:54 +0700
commitb01d0c65de49d0f0e0050d4640c6649909848320 (patch)
treed6ac4ae43ff2148b645dcabb6a69dbbb3f63ba83
parentCmce perf. opts. (diff)
downloadBouncyCastle.NET-ed25519-b01d0c65de49d0f0e0050d4640c6649909848320.tar.xz
Refactoring in Pqc.Crypto.Cmce
-rw-r--r--crypto/src/pqc/crypto/cmce/Benes.cs11
-rw-r--r--crypto/src/pqc/crypto/cmce/Benes12.cs37
-rw-r--r--crypto/src/pqc/crypto/cmce/Benes13.cs12
-rw-r--r--crypto/src/pqc/crypto/cmce/CmceKemExtractor.cs7
-rw-r--r--crypto/src/pqc/crypto/cmce/CmceKemGenerator.cs4
-rw-r--r--crypto/src/pqc/crypto/cmce/CmceKeyGenerationParameters.cs8
-rw-r--r--crypto/src/pqc/crypto/cmce/CmceKeyPairGenerator.cs24
-rw-r--r--crypto/src/pqc/crypto/cmce/CmceKeyParameters.cs10
-rw-r--r--crypto/src/pqc/crypto/cmce/CmceParameters.cs50
-rw-r--r--crypto/src/pqc/crypto/cmce/CmcePrivateKeyParameters.cs4
-rw-r--r--crypto/src/pqc/crypto/cmce/CmcePublicKeyParameters.cs18
-rw-r--r--crypto/src/pqc/crypto/cmce/Utils.cs34
12 files changed, 85 insertions, 134 deletions
diff --git a/crypto/src/pqc/crypto/cmce/Benes.cs b/crypto/src/pqc/crypto/cmce/Benes.cs
index c2141c2be..455d7946f 100644
--- a/crypto/src/pqc/crypto/cmce/Benes.cs
+++ b/crypto/src/pqc/crypto/cmce/Benes.cs
@@ -1,13 +1,13 @@
 
 namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 {
-    abstract class Benes
+    internal abstract class Benes
     {
         protected int SYS_N;
         protected int SYS_T;
         protected int GFBITS;
 
-        public Benes(int n, int t, int m)
+        internal Benes(int n, int t, int m)
         {
             SYS_N = n;
             SYS_T = t;
@@ -49,7 +49,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
                     }
                 }
             }
-
         }
 
         internal static void Transpose64x64(ulong[] output, ulong[] input, int offset)
@@ -85,10 +84,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
                     }
                 }
             }
-
         }
 
-        internal abstract protected void SupportGen(ushort[] s, byte[] c);
-
+        internal abstract void SupportGen(ushort[] s, byte[] c);
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/cmce/Benes12.cs b/crypto/src/pqc/crypto/cmce/Benes12.cs
index 5c75bd91b..bbe269066 100644
--- a/crypto/src/pqc/crypto/cmce/Benes12.cs
+++ b/crypto/src/pqc/crypto/cmce/Benes12.cs
@@ -1,15 +1,15 @@
 namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 {
-    class Benes12
+    internal class Benes12
         : Benes
     {
-        public Benes12(int n, int t, int m)
+        internal Benes12(int n, int t, int m)
             : base(n, t, m)
         {
         }
 
         /* one layer of the benes network */
-        static void LayerBenes(ulong[] data, ulong[] bits, int lgs)
+        internal static void LayerBenes(ulong[] data, ulong[] bits, int lgs)
         {
             int i, j, s;
             int bit_ptr = 0;
@@ -40,11 +40,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
             ulong[] bs = new ulong[64];
             ulong[] cond = new ulong[64];
 
-            //
-            for (i = 0; i < 64; i++)
-            {
-                bs[i] = Utils.Load8(r, i * 8);
-            }
+            Utils.Load8(r, 0, bs, 0, 64);
 
             if (rev == 0)
             {
@@ -57,8 +53,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
                 cond_ptr = SYS_T * 2 + 40 + (2 * GFBITS - 2) * 256;
             }
 
-            //
-
             Transpose64x64(bs, bs);
             for (low = 0; low <= 5; low++)
             {
@@ -77,22 +71,14 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 
             for (low = 0; low <= 5; low++)
             {
-                for (i = 0; i < 32; i++) //DONE use Utils load8
-                {
-                    cond[i] = Utils.Load8(bits, cond_ptr + i * 8);
-                }
-
+                Utils.Load8(bits, cond_ptr, cond, 0, 32);
                 LayerBenes(bs, cond, low);
                 cond_ptr += inc;
             }
 
             for (low = 4; low >= 0; low--)
             {
-                for (i = 0; i < 32; i++) //DONE use Utils load8
-                {
-                    cond[i] = Utils.Load8(bits, cond_ptr + i * 8);
-                }
-
+                Utils.Load8(bits, cond_ptr, cond, 0, 32);
                 LayerBenes(bs, cond, low);
                 cond_ptr += inc;
             }
@@ -113,16 +99,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 
             Transpose64x64(bs, bs);
 
-            //
-            for (i = 0; i < 64; i++)
-            {
-                Utils.Store8(r, i * 8, bs[i]);
-
-            }
+            Utils.Store8(r, 0, bs, 0, 64);
         }
 
         // from benes network
-        protected internal override void SupportGen(ushort[] s, byte[] c)
+        internal override void SupportGen(ushort[] s, byte[] c)
         {
             ushort a;
             byte[][] L = new byte[GFBITS][]; //(1 << GFBITS)/8
@@ -161,4 +142,4 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/cmce/Benes13.cs b/crypto/src/pqc/crypto/cmce/Benes13.cs
index c921349c0..2119fe478 100644
--- a/crypto/src/pqc/crypto/cmce/Benes13.cs
+++ b/crypto/src/pqc/crypto/cmce/Benes13.cs
@@ -1,15 +1,15 @@
 namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 {
-    class Benes13
+    internal class Benes13
         : Benes
     {
-        public Benes13(int n, int t, int m)
+        internal Benes13(int n, int t, int m)
             : base(n, t, m)
         {
         }
 
         /* middle layers of the benes network */
-        static void LayerIn(ulong[] data, ulong[] bits, int lgs)
+        internal static void LayerIn(ulong[] data, ulong[] bits, int lgs)
         {
             int i, j, s;
             int bit_ptr = 0;
@@ -36,7 +36,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
         }
 
         /* first and last layers of the benes network */
-        static void LayerEx(ulong[] data, ulong[] bits, int lgs)
+        internal static void LayerEx(ulong[] data, ulong[] bits, int lgs)
         {
             int i, j, s;
             int bit_ptr = 0;
@@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
         /*        bits, condition bits of the Benes network */
         /*        rev, 0 for normal application; !0 for inverse */
         /* output: r, permuted bits */
-        void ApplyBenes(byte[] r, byte[] bits, int rev)
+        internal void ApplyBenes(byte[] r, byte[] bits, int rev)
         {
             int i, iter, inc;
 
@@ -171,7 +171,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 
         /* input: condition bits c */
         /* output: support s */
-        protected internal override void SupportGen(ushort[] s, byte[] c)
+        internal override void SupportGen(ushort[] s, byte[] c)
         {
             ushort a;
             int i, j;
diff --git a/crypto/src/pqc/crypto/cmce/CmceKemExtractor.cs b/crypto/src/pqc/crypto/cmce/CmceKemExtractor.cs
index d65f20d2b..51cef8ff0 100644
--- a/crypto/src/pqc/crypto/cmce/CmceKemExtractor.cs
+++ b/crypto/src/pqc/crypto/cmce/CmceKemExtractor.cs
@@ -1,10 +1,8 @@
-using System;
-
 using Org.BouncyCastle.Crypto;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 {
-    public class CmceKemExtractor
+    public sealed class CmceKemExtractor
         : IEncapsulatedSecretExtractor
     {
         private CmceEngine engine;
@@ -23,7 +21,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
             CmcePrivateKeyParameters privateParams = (CmcePrivateKeyParameters)key;
             if (privateParams.privateKey.Length < engine.PrivateKeySize)
             {
-                key = new CmcePrivateKeyParameters(privateParams.Parameters, engine.decompress_private_key(privateParams.privateKey));
+                key = new CmcePrivateKeyParameters(privateParams.Parameters,
+                    engine.decompress_private_key(privateParams.privateKey));
             }
         }
 
diff --git a/crypto/src/pqc/crypto/cmce/CmceKemGenerator.cs b/crypto/src/pqc/crypto/cmce/CmceKemGenerator.cs
index 657da509c..4ac145e3f 100644
--- a/crypto/src/pqc/crypto/cmce/CmceKemGenerator.cs
+++ b/crypto/src/pqc/crypto/cmce/CmceKemGenerator.cs
@@ -4,11 +4,11 @@ using Org.BouncyCastle.Security;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 {
-    public class CmceKemGenerator
+    public sealed class CmceKemGenerator
         : IEncapsulatedSecretGenerator
     {
         // the source of randomness
-        private SecureRandom sr;
+        private readonly SecureRandom sr;
 
         public CmceKemGenerator(SecureRandom random)
         {
diff --git a/crypto/src/pqc/crypto/cmce/CmceKeyGenerationParameters.cs b/crypto/src/pqc/crypto/cmce/CmceKeyGenerationParameters.cs
index a1507712e..1bac7419f 100644
--- a/crypto/src/pqc/crypto/cmce/CmceKeyGenerationParameters.cs
+++ b/crypto/src/pqc/crypto/cmce/CmceKeyGenerationParameters.cs
@@ -1,18 +1,14 @@
-using System;
-
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Security;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 {
-    public class CmceKeyGenerationParameters
+    public sealed class CmceKeyGenerationParameters
         : KeyGenerationParameters
     {
         private CmceParameters parameters;
 
-        public CmceKeyGenerationParameters(
-            SecureRandom random,
-            CmceParameters CmceParams)
+        public CmceKeyGenerationParameters(SecureRandom random, CmceParameters CmceParams)
             : base(random, 256)
         {
             this.parameters = CmceParams;
diff --git a/crypto/src/pqc/crypto/cmce/CmceKeyPairGenerator.cs b/crypto/src/pqc/crypto/cmce/CmceKeyPairGenerator.cs
index 911b1a6b0..f2adc884c 100644
--- a/crypto/src/pqc/crypto/cmce/CmceKeyPairGenerator.cs
+++ b/crypto/src/pqc/crypto/cmce/CmceKeyPairGenerator.cs
@@ -1,43 +1,31 @@
-using System;
-
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Security;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 {
-    public class CmceKeyPairGenerator
+    public sealed class CmceKeyPairGenerator
         : IAsymmetricCipherKeyPairGenerator
     {
-        private CmceKeyGenerationParameters CmceParams;
-
-        private int m;
-
-        private int n;
-
-        private int t;
+        private CmceKeyGenerationParameters m_cmceParams;
 
         private SecureRandom random;
 
         private void Initialize(
             KeyGenerationParameters param)
         {
-            this.CmceParams = (CmceKeyGenerationParameters) param;
+            this.m_cmceParams = (CmceKeyGenerationParameters) param;
             this.random = param.Random;
-
-            this.m = this.CmceParams.Parameters.M;
-            this.n = this.CmceParams.Parameters.N;
-            this.t = this.CmceParams.Parameters.T;
         }
 
         private AsymmetricCipherKeyPair GenKeyPair()
         {
-            CmceEngine engine = CmceParams.Parameters.Engine;
+            CmceEngine engine = m_cmceParams.Parameters.Engine;
             byte[] sk = new byte[engine.PrivateKeySize];
             byte[] pk = new byte[engine.PublicKeySize];
             engine.kem_keypair(pk, sk, random);
 
-            CmcePublicKeyParameters pubKey = new CmcePublicKeyParameters(CmceParams.Parameters, pk);
-            CmcePrivateKeyParameters privKey = new CmcePrivateKeyParameters(CmceParams.Parameters, sk);
+            CmcePublicKeyParameters pubKey = new CmcePublicKeyParameters(m_cmceParams.Parameters, pk);
+            CmcePrivateKeyParameters privKey = new CmcePrivateKeyParameters(m_cmceParams.Parameters, sk);
             return new AsymmetricCipherKeyPair(pubKey, privKey);
 
         }
diff --git a/crypto/src/pqc/crypto/cmce/CmceKeyParameters.cs b/crypto/src/pqc/crypto/cmce/CmceKeyParameters.cs
index 861d518c6..e66fb66d1 100644
--- a/crypto/src/pqc/crypto/cmce/CmceKeyParameters.cs
+++ b/crypto/src/pqc/crypto/cmce/CmceKeyParameters.cs
@@ -1,17 +1,13 @@
-using System;
-
 using Org.BouncyCastle.Crypto;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 {
-    public class CmceKeyParameters
+    public abstract class CmceKeyParameters
         : AsymmetricKeyParameter
     {
-        private CmceParameters parameters;
+        private readonly CmceParameters parameters;
 
-        public CmceKeyParameters(
-            bool isPrivate,
-            CmceParameters parameters)
+        internal CmceKeyParameters(bool isPrivate, CmceParameters parameters)
             : base(isPrivate)
         {
             this.parameters = parameters;
diff --git a/crypto/src/pqc/crypto/cmce/CmceParameters.cs b/crypto/src/pqc/crypto/cmce/CmceParameters.cs
index 3974e2845..53932bd77 100644
--- a/crypto/src/pqc/crypto/cmce/CmceParameters.cs
+++ b/crypto/src/pqc/crypto/cmce/CmceParameters.cs
@@ -2,53 +2,53 @@ using Org.BouncyCastle.Crypto;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 {
-    public class CmceParameters
+    public sealed class CmceParameters
         : ICipherParameters
     {
-        private static int[] poly3488 = new int[] {3, 1, 0};
-        private static int[] poly4608 = new int[] {10, 9, 6, 0};
-        private static int[] poly6688 = new int[] {7, 2, 1, 0};
-        private static int[] poly6960 = new int[] {8, 0};
-        private static int[] poly8192 = new int[] {7, 2, 1, 0};
+        private static readonly int[] poly3488 = new int[] {3, 1, 0};
+        private static readonly int[] poly4608 = new int[] {10, 9, 6, 0};
+        private static readonly int[] poly6688 = new int[] {7, 2, 1, 0};
+        private static readonly int[] poly6960 = new int[] {8, 0};
+        private static readonly int[] poly8192 = new int[] {7, 2, 1, 0};
 
-        public static CmceParameters mceliece348864r3 =
+        public static readonly CmceParameters mceliece348864r3 =
             new CmceParameters("mceliece348864", 12, 3488, 64, poly3488, false, 128);
 
-        public static CmceParameters mceliece348864fr3 =
+        public static readonly CmceParameters mceliece348864fr3 =
             new CmceParameters("mceliece348864f", 12, 3488, 64, poly3488, true, 128);
 
-        public static CmceParameters mceliece460896r3 =
+        public static readonly CmceParameters mceliece460896r3 =
             new CmceParameters("mceliece460896", 13, 4608, 96, poly4608, false, 192);
 
-        public static CmceParameters mceliece460896fr3 =
+        public static readonly CmceParameters mceliece460896fr3 =
             new CmceParameters("mceliece460896f", 13, 4608, 96, poly4608, true, 192);
 
-        public static CmceParameters mceliece6688128r3 =
+        public static readonly CmceParameters mceliece6688128r3 =
             new CmceParameters("mceliece6688128", 13, 6688, 128, poly6688, false, 256);
 
-        public static CmceParameters mceliece6688128fr3 =
+        public static readonly CmceParameters mceliece6688128fr3 =
             new CmceParameters("mceliece6688128f", 13, 6688, 128, poly6688, true, 256);
 
-        public static CmceParameters mceliece6960119r3 =
+        public static readonly CmceParameters mceliece6960119r3 =
             new CmceParameters("mceliece6960119", 13, 6960, 119, poly6960, false, 256);
 
-        public static CmceParameters mceliece6960119fr3 =
+        public static readonly CmceParameters mceliece6960119fr3 =
             new CmceParameters("mceliece6960119f", 13, 6960, 119, poly6960, true, 256);
 
-        public static CmceParameters mceliece8192128r3 =
+        public static readonly CmceParameters mceliece8192128r3 =
             new CmceParameters("mceliece8192128", 13, 8192, 128, poly8192, false, 256);
 
-        public static CmceParameters mceliece8192128fr3 =
+        public static readonly CmceParameters mceliece8192128fr3 =
             new CmceParameters("mceliece8192128f", 13, 8192, 128, poly8192, true, 256);
 
-        private string name;
-        private int m;
-        private int n;
-        private int t;
-        private int[] poly;
-        private bool usePivots;
-        private int defaultKeySize;
-        private CmceEngine engine;
+        private readonly string name;
+        private readonly int m;
+        private readonly int n;
+        private readonly int t;
+        //private readonly int[] poly;
+        private readonly bool usePivots;
+        private readonly int defaultKeySize;
+        private readonly CmceEngine engine;
 
         private CmceParameters(string name, int m, int n, int t, int[] p, bool usePivots, int defaultKeySize)
         {
@@ -56,7 +56,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
             this.m = m;
             this.n = n;
             this.t = t;
-            this.poly = p;
+            //this.poly = p;
             this.usePivots = usePivots;
             this.defaultKeySize = defaultKeySize;
             this.engine = new CmceEngine(m, n, t, p, usePivots, defaultKeySize);
diff --git a/crypto/src/pqc/crypto/cmce/CmcePrivateKeyParameters.cs b/crypto/src/pqc/crypto/cmce/CmcePrivateKeyParameters.cs
index 1331aea14..a30f44469 100644
--- a/crypto/src/pqc/crypto/cmce/CmcePrivateKeyParameters.cs
+++ b/crypto/src/pqc/crypto/cmce/CmcePrivateKeyParameters.cs
@@ -4,10 +4,10 @@ using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 {
-    public class CmcePrivateKeyParameters
+    public sealed class CmcePrivateKeyParameters
         : CmceKeyParameters
     {
-        internal byte[] privateKey;
+        internal readonly byte[] privateKey;
 
         public byte[] GetPrivateKey()
         {
diff --git a/crypto/src/pqc/crypto/cmce/CmcePublicKeyParameters.cs b/crypto/src/pqc/crypto/cmce/CmcePublicKeyParameters.cs
index e394f643d..f70c6ff03 100644
--- a/crypto/src/pqc/crypto/cmce/CmcePublicKeyParameters.cs
+++ b/crypto/src/pqc/crypto/cmce/CmcePublicKeyParameters.cs
@@ -1,13 +1,17 @@
-using System;
-
 using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 {
-    public class CmcePublicKeyParameters
+    public sealed class CmcePublicKeyParameters
         : CmceKeyParameters
     {
-        internal byte[] publicKey;
+        internal readonly byte[] publicKey;
+
+        public CmcePublicKeyParameters(CmceParameters parameters, byte[] publicKey)
+            : base(false, parameters)
+        {
+            this.publicKey = Arrays.Clone(publicKey);
+        }
 
         public byte[] GetPublicKey()
         { 
@@ -18,11 +22,5 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
         {
             return GetPublicKey();
         }
-
-        public CmcePublicKeyParameters(CmceParameters parameters, byte[] publicKey)
-            : base(false,  parameters)
-        {
-            this.publicKey = Arrays.Clone(publicKey);
-        }
     }
 }
diff --git a/crypto/src/pqc/crypto/cmce/Utils.cs b/crypto/src/pqc/crypto/cmce/Utils.cs
index 85eadb953..0ebe168b1 100644
--- a/crypto/src/pqc/crypto/cmce/Utils.cs
+++ b/crypto/src/pqc/crypto/cmce/Utils.cs
@@ -1,20 +1,17 @@
-
 using Org.BouncyCastle.Crypto.Utilities;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 {
-
-    class Utils
+    internal class Utils
     {
         internal static void StoreGF(byte[] dest, int offset, ushort a)
         {
-            dest[offset + 0] = (byte) (a & 0xFF);
-            dest[offset + 1] = (byte) (a >> 8);
+            Pack.UInt16_To_LE(a, dest, offset);
         }
 
         internal static ushort LoadGF(byte[] src, int offset, int gfmask)
         {
-            return (ushort) (Pack.LE_To_UInt16(src, offset) & gfmask);
+            return (ushort)(Pack.LE_To_UInt16(src, offset) & gfmask);
         }
 
         internal static uint Load4(byte[] input, int offset)
@@ -24,15 +21,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
 
         internal static void Store8(byte[] output, int offset, ulong input)
         {
-            //use pack
-            output[offset + 0] = (byte) ((input >> 0x00) & 0xFF);
-            output[offset + 1] = (byte) ((input >> 0x08) & 0xFF);
-            output[offset + 2] = (byte) ((input >> 0x10) & 0xFF);
-            output[offset + 3] = (byte) ((input >> 0x18) & 0xFF);
-            output[offset + 4] = (byte) ((input >> 0x20) & 0xFF);
-            output[offset + 5] = (byte) ((input >> 0x28) & 0xFF);
-            output[offset + 6] = (byte) ((input >> 0x30) & 0xFF);
-            output[offset + 7] = (byte) ((input >> 0x38) & 0xFF);
+            Pack.UInt64_To_LE(input, output, offset);
+        }
+
+        internal static void Store8(byte[] output, int offset, ulong[] input, int inOff, int inLen)
+        {
+            Pack.UInt64_To_LE(input, inOff, inLen, output, offset);
         }
 
         internal static ulong Load8(byte[] input, int offset)
@@ -40,16 +34,18 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
             return Pack.LE_To_UInt64(input, offset);
         }
 
+        internal static void Load8(byte[] input, int offset, ulong[] output, int outOff, int outLen)
+        {
+            Pack.LE_To_UInt64(input, offset, output, outOff, outLen);
+        }
+
         internal static ushort Bitrev(ushort a, int GFBITS)
         {
             a = (ushort) (((a & 0x00FF) << 8) | ((a & 0xFF00) >> 8));
             a = (ushort) (((a & 0x0F0F) << 4) | ((a & 0xF0F0) >> 4));
             a = (ushort) (((a & 0x3333) << 2) | ((a & 0xCCCC) >> 2));
             a = (ushort) (((a & 0x5555) << 1) | ((a & 0xAAAA) >> 1));
-            if (GFBITS == 12)
-                return (ushort) (a >> 4);
-            return (ushort) (a >> 3);
+            return (ushort)(a >> (16 - GFBITS));
         }
-
     }
 }