summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-10-06 18:19:39 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-10-06 18:19:39 +0700
commit1ccff196bfcbe24de6f892b493cf80e607340eee (patch)
tree35d27ef002e24848a26a7aeafa966d5f8898a66b
parentFix extraneous using (diff)
downloadBouncyCastle.NET-ed25519-1ccff196bfcbe24de6f892b493cf80e607340eee.tar.xz
Refactoring pass over Pqc.Crypto.Lms
-rw-r--r--crypto/src/crypto/util/Pack.cs7
-rw-r--r--crypto/src/pqc/crypto/lms/Composer.cs110
-rw-r--r--crypto/src/pqc/crypto/lms/HSS.cs80
-rw-r--r--crypto/src/pqc/crypto/lms/HSSKeyGenerationParameters.cs40
-rw-r--r--crypto/src/pqc/crypto/lms/HSSKeyPairGenerator.cs14
-rw-r--r--crypto/src/pqc/crypto/lms/HSSPrivateKeyParameters.cs143
-rw-r--r--crypto/src/pqc/crypto/lms/HSSPublicKeyParameters.cs78
-rw-r--r--crypto/src/pqc/crypto/lms/HSSSignature.cs33
-rw-r--r--crypto/src/pqc/crypto/lms/HSSSigner.cs2
-rw-r--r--crypto/src/pqc/crypto/lms/LMOtsParameters.cs95
-rw-r--r--crypto/src/pqc/crypto/lms/LMOtsPrivateKey.cs69
-rw-r--r--crypto/src/pqc/crypto/lms/LMOtsPublicKey.cs138
-rw-r--r--crypto/src/pqc/crypto/lms/LMOtsSignature.cs102
-rw-r--r--crypto/src/pqc/crypto/lms/LMS.cs31
-rw-r--r--crypto/src/pqc/crypto/lms/LMSContext.cs125
-rw-r--r--crypto/src/pqc/crypto/lms/LMSKeyGenerationParameters.cs11
-rw-r--r--crypto/src/pqc/crypto/lms/LMSKeyPairGenerator.cs17
-rw-r--r--crypto/src/pqc/crypto/lms/LMSKeyParameters.cs10
-rw-r--r--crypto/src/pqc/crypto/lms/LMSParameters.cs24
-rw-r--r--crypto/src/pqc/crypto/lms/LMSPrivateKeyParameters.cs40
-rw-r--r--crypto/src/pqc/crypto/lms/LMSPublicKeyParameters.cs48
-rw-r--r--crypto/src/pqc/crypto/lms/LMSSignature.cs55
-rw-r--r--crypto/src/pqc/crypto/lms/LMSSignedPubKey.cs1
-rw-r--r--crypto/src/pqc/crypto/lms/LMSSigner.cs16
-rw-r--r--crypto/src/pqc/crypto/lms/LMSigParameters.cs65
-rw-r--r--crypto/src/pqc/crypto/lms/LM_OTS.cs118
-rw-r--r--crypto/src/pqc/crypto/lms/LmsUtils.cs11
-rw-r--r--crypto/src/pqc/crypto/lms/SeedDerive.cs105
-rw-r--r--crypto/src/pqc/crypto/sphincsplus/Adrs.cs3
-rw-r--r--crypto/src/pqc/crypto/utils/PrivateKeyInfoFactory.cs2
-rw-r--r--crypto/test/src/pqc/crypto/lms/HSSTests.cs65
-rw-r--r--crypto/test/src/pqc/crypto/lms/LMSKeyGenTests.cs3
-rw-r--r--crypto/test/src/pqc/crypto/lms/LMSTests.cs27
-rw-r--r--crypto/test/src/pqc/crypto/test/HSSTest.cs6
34 files changed, 698 insertions, 996 deletions
diff --git a/crypto/src/crypto/util/Pack.cs b/crypto/src/crypto/util/Pack.cs
index d258c8168..f5bffb08a 100644
--- a/crypto/src/crypto/util/Pack.cs
+++ b/crypto/src/crypto/util/Pack.cs
@@ -524,6 +524,13 @@ namespace Org.BouncyCastle.Crypto.Utilities
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        internal static void UInt16_To_BE(ushort n, Span<byte> bs)
+        {
+            bs[0] = (byte)(n >> 8);
+            bs[1] = (byte)n;
+        }
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal static void UInt32_To_BE(uint n, Span<byte> bs)
         {
             bs[0] = (byte)(n >> 24);
diff --git a/crypto/src/pqc/crypto/lms/Composer.cs b/crypto/src/pqc/crypto/lms/Composer.cs
index 437c86d65..b897f4b68 100644
--- a/crypto/src/pqc/crypto/lms/Composer.cs
+++ b/crypto/src/pqc/crypto/lms/Composer.cs
@@ -1,5 +1,6 @@
 using System;
 using System.IO;
+
 using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
@@ -7,14 +8,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
     /**
     * Type to assist in build LMS messages.
     */
-    public class Composer
+    public sealed class Composer
     {
         //Todo make sure MemoryStream works properly (not sure about byte arrays as inputs)
-        private MemoryStream bos = new MemoryStream();
+        private readonly MemoryStream bos = new MemoryStream();
 
         private Composer()
         {
-
         }
 
         public static Composer Compose()
@@ -24,9 +24,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
         public Composer U64Str(long n)
         {
-            U32Str((int) (n >> 32));
-            U32Str((int) n);
-
+            U32Str((int)(n >> 32));
+            U32Str((int)n);
             return this;
         }
 
@@ -35,7 +34,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             bos.WriteByte((byte)(n >> 24));
             bos.WriteByte((byte)(n >> 16));
             bos.WriteByte((byte)(n >> 8));
-            bos.WriteByte((byte)(n));
+            bos.WriteByte((byte)n);
             return this;
         }
 
@@ -43,39 +42,24 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         {
             n &= 0xFFFF;
             bos.WriteByte((byte)(n >> 8));
-            bos.WriteByte((byte)(n));
+            bos.WriteByte((byte)n);
             return this;
         }
 
         public Composer Bytes(IEncodable[] encodable)
         {
-            try
-            {
-                foreach (var e in encodable)
-                {
-                    bos.Write(e.GetEncoded(), 0, e.GetEncoded().Length);// todo count?
-                }
-            }
-            catch (Exception ex)
+            foreach (var e in encodable)
             {
-                throw new Exception(ex.Message, ex);
+                byte[] encoding = e.GetEncoded();
+                bos.Write(encoding, 0, encoding.Length);// todo count?
             }
-
             return this;
         }
 
-
         public Composer Bytes(IEncodable encodable)
         {
-            try
-            {
-                bos.Write(encodable.GetEncoded(), 0, encodable.GetEncoded().Length);
-            }
-            catch (Exception ex)
-            {
-                throw new Exception(ex.Message, ex);
-            }
-
+            byte[] encoding = encodable.GetEncoded();
+            bos.Write(encoding, 0, encoding.Length);
             return this;
         }
 
@@ -83,82 +67,40 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         {
             for (; len >= 0; len--)
             {
-                try
-                {
-                    bos.WriteByte((byte) v);
-                }
-                catch (Exception ex)
-                {
-                    throw new Exception(ex.Message, ex);
-                }
+                bos.WriteByte((byte)v);
             }
-
             return this;
         }
 
         public Composer Bytes(byte[][] arrays)
         {
-            try
-            {
-                foreach (byte[] array in arrays)
-                {
-                    bos.Write(array, 0, array.Length); //todo count?
-                }
-            }
-            catch (Exception ex)
+            foreach (byte[] array in arrays)
             {
-                throw new Exception(ex.Message, ex);
+                bos.Write(array, 0, array.Length); //todo count?
             }
-
             return this;
         }
 
         public Composer Bytes(byte[][] arrays, int start, int end)
         {
-            try
+            int j = start;
+            while (j != end)
             {
-                int j = start;
-                while (j != end)
-                {
-                    bos.Write(arrays[j], 0, arrays[j].Length);//todo count?
-                    j++;
-                }
+                bos.Write(arrays[j], 0, arrays[j].Length);//todo count?
+                j++;
             }
-            catch (Exception ex)
-            {
-                throw new Exception(ex.Message, ex);
-            }
-
             return this;
         }
 
-
         public Composer Bytes(byte[] array)
         {
-            try
-            {
-                bos.Write(array, 0, array.Length);//todo count?
-            }
-            catch (Exception ex)
-            {
-                throw new Exception(ex.Message, ex);
-            }
-
+            bos.Write(array, 0, array.Length);//todo count?
             return this;
         }
 
-
         public Composer Bytes(byte[] array, int start, int len)
         {
-            try
-            {
-                bos.Write(array, start, len);
-            }
-            catch (Exception ex)
-            {
-                throw new Exception(ex.Message, ex);
-            }
-
+            bos.Write(array, start, len);
             return this;
         }
 
@@ -171,17 +113,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         {
             while (bos.Length < requiredLen)
             {
-                bos.WriteByte((byte) v);
+                bos.WriteByte((byte)v);
             }
-
             return this;
         }
 
-        public Composer GetBool(bool v)
+        public Composer Boolean(bool v)
         {
-            bos.WriteByte((byte) (v ? 1 : 0));
+            bos.WriteByte((byte)(v ? 1 : 0));
             return this;
         }
-            
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/HSS.cs b/crypto/src/pqc/crypto/lms/HSS.cs
index 556ffac26..77c5fdab0 100644
--- a/crypto/src/pqc/crypto/lms/HSS.cs
+++ b/crypto/src/pqc/crypto/lms/HSS.cs
@@ -10,8 +10,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             //
             // LmsPrivateKey can derive and hold the public key so we just use an array of those.
             //
-            LMSPrivateKeyParameters[] keys = new LMSPrivateKeyParameters[parameters.GetDepth()];
-            LMSSignature[] sig = new LMSSignature[parameters.GetDepth() - 1];
+            LMSPrivateKeyParameters[] keys = new LMSPrivateKeyParameters[parameters.Depth];
+            LMSSignature[] sig = new LMSSignature[parameters.Depth - 1];
 
             byte[] rootSeed = new byte[32];
             parameters.Random.NextBytes(rootSeed);
@@ -30,27 +30,28 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             long hssKeyMaxIndex = 1;
             for (int t = 0; t < keys.Length; t++)
             {
+                var lms = parameters.GetLmsParameters(t);
                 if (t == 0)
                 {
                     keys[t] = new LMSPrivateKeyParameters(
-                        parameters.GetLmsParameters()[t].GetLmSigParam(),
-                        parameters.GetLmsParameters()[t].GetLmotsParam(),
+                        lms.LMSigParameters,
+                        lms.LMOtsParameters,
                         0,
                         I,
-                        1 << parameters.GetLmsParameters()[t].GetLmSigParam().GetH(),
+                        1 << lms.LMSigParameters.H,
                         rootSeed);
                 }
                 else
                 {
                     keys[t] = new PlaceholderLMSPrivateKey(
-                        parameters.GetLmsParameters()[t].GetLmSigParam(),
-                        parameters.GetLmsParameters()[t].GetLmotsParam(),
+                        lms.LMSigParameters,
+                        lms.LMOtsParameters,
                         -1,
                         zero,
-                        1 << parameters.GetLmsParameters()[t].GetLmSigParam().GetH(),
+                        1 << lms.LMSigParameters.H,
                         zero);
                 }
-                hssKeyMaxIndex *= 1 << parameters.GetLmsParameters()[t].GetLmSigParam().GetH();
+                hssKeyMaxIndex <<= lms.LMSigParameters.H;
             }
 
             // if this has happened we're trying to generate a really large key
@@ -61,7 +62,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             }
 
             return new HSSPrivateKeyParameters(
-                parameters.GetDepth(),
+                parameters.Depth,
                 new List<LMSPrivateKeyParameters>(keys),
                 new List<LMSSignature>(sig),
                 0, hssKeyMaxIndex);
@@ -82,11 +83,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             {
                 RangeTestKeys(keyPair);
                 keyPair.IncIndex();
-                (keyPair.GetKeys()[(keyPair.L - 1)] as LMSPrivateKeyParameters).IncIndex();
+                keyPair.GetKeys()[keyPair.L - 1].IncIndex();
             }
         }
 
-
         public static void RangeTestKeys(HSSPrivateKeyParameters keyPair)
         {
             lock (keyPair)
@@ -99,27 +99,19 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                             " is exhausted");
                 }
 
-
                 int L = keyPair.L;
                 int d = L;
                 var prv = keyPair.GetKeys();
-                while ((prv[d - 1] as LMSPrivateKeyParameters).GetIndex() == 1 << ((prv[(d - 1)] as LMSPrivateKeyParameters ).GetSigParameters().GetH()))
+                while (prv[d - 1].GetIndex() == 1 << prv[d - 1].GetSigParameters().H)
                 {
-                    d = d - 1;
-                    if (d == 0)
-                    {
-                        throw new Exception(
-                            "hss private key" +
-                                ((keyPair.IsShard()) ? " shard" : "") +
-                                " is exhausted the maximum limit for this HSS private key");
-                    }
+                    if (--d == 0)
+                        throw new Exception("hss private key" + (keyPair.IsShard() ? " shard" : "") +
+                            " is exhausted the maximum limit for this HSS private key");
                 }
 
-
                 while (d < L)
                 {
-                    keyPair.ReplaceConsumedKey(d);
-                    d = d + 1;
+                    keyPair.ReplaceConsumedKey(d++);
                 }
             }
         }
@@ -138,17 +130,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                 var keys = keyPair.GetKeys();
                 var sig = keyPair.GetSig();
 
-                nextKey = keyPair.GetKeys()[L - 1] as LMSPrivateKeyParameters;
+                nextKey = keyPair.GetKeys()[L - 1];
 
                 // Step 2. Stand in for sig[L-1]
                 int i = 0;
                 signed_pub_key = new LMSSignedPubKey[L - 1];
                 while (i < L - 1)
                 {
-                    signed_pub_key[i] = new LMSSignedPubKey(
-                        sig[i] as LMSSignature,
-                        (keys[i + 1] as LMSPrivateKeyParameters).GetPublicKey());
-                    i = i + 1;
+                    signed_pub_key[i] = new LMSSignedPubKey(sig[i], keys[i + 1].GetPublicKey());
+                    ++i;
                 }
 
                 //
@@ -166,28 +156,26 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
         public static HSSSignature GenerateSignature(int L, LMSContext context)
         {
-            return new HSSSignature(L - 1, context.GetSignedPubKeys(), LMS.GenerateSign(context));
+            return new HSSSignature(L - 1, context.SignedPubKeys, LMS.GenerateSign(context));
         }
 
         public static bool VerifySignature(HSSPublicKeyParameters publicKey, HSSSignature signature, byte[] message)
         {
             int Nspk = signature.GetlMinus1();
-            if (Nspk + 1 != publicKey.GetL())
-            {
+            if (Nspk + 1 != publicKey.L)
                 return false;
-            }
 
             LMSSignature[] sigList = new LMSSignature[Nspk + 1];
             LMSPublicKeyParameters[] pubList = new LMSPublicKeyParameters[Nspk];
 
             for (int i = 0; i < Nspk; i++)
             {
-                sigList[i] = signature.GetSignedPubKey()[i].GetSignature();
-                pubList[i] = signature.GetSignedPubKey()[i].GetPublicKey();
+                sigList[i] = signature.GetSignedPubKeys()[i].GetSignature();
+                pubList[i] = signature.GetSignedPubKeys()[i].GetPublicKey();
             }
-            sigList[Nspk] = signature.GetSignature();
+            sigList[Nspk] = signature.Signature;
 
-            LMSPublicKeyParameters key = publicKey.GetLmsPublicKey();
+            LMSPublicKeyParameters key = publicKey.LmsPublicKey;
 
             for (int i = 0; i < Nspk; i++)
             {
@@ -209,24 +197,24 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             return LMS.VerifySignature(key, sigList[Nspk], message);
         }
 
-
-        class PlaceholderLMSPrivateKey
+        private class PlaceholderLMSPrivateKey
             : LMSPrivateKeyParameters
         {
-
-            public PlaceholderLMSPrivateKey(LMSigParameters lmsParameter, LMOtsParameters otsParameters, int q, byte[] I, int maxQ, byte[] masterSecret)
+            internal PlaceholderLMSPrivateKey(LMSigParameters lmsParameter, LMOtsParameters otsParameters, int q,
+                byte[] I, int maxQ, byte[] masterSecret)
                 : base(lmsParameter, otsParameters, q, I, maxQ, masterSecret)
-            {}
+            {
+            }
 
-            LMOtsPrivateKey GetNextOtsPrivateKey()
+            internal override LMOtsPrivateKey GetNextOtsPrivateKey()
             {
                 throw new Exception("placeholder only");
             }
 
-            public LMSPublicKeyParameters GetPublicKey()
+            public override LMSPublicKeyParameters GetPublicKey()
             {
                 throw new Exception("placeholder only");
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/HSSKeyGenerationParameters.cs b/crypto/src/pqc/crypto/lms/HSSKeyGenerationParameters.cs
index e7a2403aa..5baaa7aa2 100644
--- a/crypto/src/pqc/crypto/lms/HSSKeyGenerationParameters.cs
+++ b/crypto/src/pqc/crypto/lms/HSSKeyGenerationParameters.cs
@@ -1,13 +1,23 @@
 using System;
+
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Security;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-    public class HSSKeyGenerationParameters
+    public sealed class HSSKeyGenerationParameters
         : KeyGenerationParameters
     {
-        private LMSParameters[] lmsParameters;
+        private static LMSParameters[] ValidateLmsParameters(LMSParameters[] lmsParameters)
+        {
+            if (lmsParameters == null)
+                throw new ArgumentNullException(nameof(lmsParameters));
+            if (lmsParameters.Length < 1 || lmsParameters.Length > 8)  // RFC 8554, Section 6.
+                throw new ArgumentException("length should be between 1 and 8 inclusive", nameof(lmsParameters));
+            return lmsParameters;
+        }
+
+        private readonly LMSParameters[] m_lmsParameters;
 
         /**
          * Base constructor - parameters and a source of randomness.
@@ -15,26 +25,20 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
          * @param lmsParameters array of LMS parameters, one per level in the hierarchy (up to 8 levels).
          * @param random   the random byte source.
          */
-        public HSSKeyGenerationParameters(
-            LMSParameters[] lmsParameters,
-            SecureRandom random)
-            :base(random, LmsUtils.CalculateStrength(lmsParameters[0]))
+        public HSSKeyGenerationParameters(LMSParameters[] lmsParameters, SecureRandom random)
+            :base(random, LmsUtils.CalculateStrength(ValidateLmsParameters(lmsParameters)[0]))
         {
-            if (lmsParameters.Length == 0 || lmsParameters.Length > 8)  // RFC 8554, Section 6.
-            {
-                throw new ArgumentException("lmsParameters length should be between 1 and 8 inclusive");
-            }
-            this.lmsParameters = lmsParameters;
+            m_lmsParameters = lmsParameters;
         }
 
-        public int GetDepth()
-        {
-            return lmsParameters.Length;
-        }
+        public int Depth => m_lmsParameters.Length;
 
-        public LMSParameters[] GetLmsParameters()
+        public LMSParameters GetLmsParameters(int index)
         {
-            return lmsParameters;
+            if (index < 0 || index >= m_lmsParameters.Length)
+                throw new ArgumentOutOfRangeException(nameof(index));
+
+            return m_lmsParameters[index];
         }
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/HSSKeyPairGenerator.cs b/crypto/src/pqc/crypto/lms/HSSKeyPairGenerator.cs
index 562679563..137275a9a 100644
--- a/crypto/src/pqc/crypto/lms/HSSKeyPairGenerator.cs
+++ b/crypto/src/pqc/crypto/lms/HSSKeyPairGenerator.cs
@@ -2,21 +2,21 @@ using Org.BouncyCastle.Crypto;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-    public class HSSKeyPairGenerator
-    : IAsymmetricCipherKeyPairGenerator
+    public sealed class HSSKeyPairGenerator
+        : IAsymmetricCipherKeyPairGenerator
     {
-        HSSKeyGenerationParameters param;
+        private HSSKeyGenerationParameters m_parameters;
 
-        public void Init(KeyGenerationParameters param)
+        public void Init(KeyGenerationParameters parameters)
         {
-            this.param = (HSSKeyGenerationParameters) param;
+            m_parameters = (HSSKeyGenerationParameters)parameters;
         }
 
         public AsymmetricCipherKeyPair GenerateKeyPair()
         {
-            HSSPrivateKeyParameters privKey = HSS.GenerateHssKeyPair(param);
+            HSSPrivateKeyParameters privKey = HSS.GenerateHssKeyPair(m_parameters);
 
             return new AsymmetricCipherKeyPair(privKey.GetPublicKey(), privKey);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/HSSPrivateKeyParameters.cs b/crypto/src/pqc/crypto/lms/HSSPrivateKeyParameters.cs
index fc85af1aa..bcbccef1a 100644
--- a/crypto/src/pqc/crypto/lms/HSSPrivateKeyParameters.cs
+++ b/crypto/src/pqc/crypto/lms/HSSPrivateKeyParameters.cs
@@ -6,8 +6,6 @@ using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.IO;
 
-// using static Org.BouncyCastle.Pqc.Crypto.Lms.HSS.rangeTestKeys;
-
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
     public class HSSPrivateKeyParameters
@@ -65,35 +63,34 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
         public static HSSPrivateKeyParameters GetInstance(Object src)
         {
-            if (src is HSSPrivateKeyParameters)
+            if (src is HSSPrivateKeyParameters hssPrivateKeyParameters)
             {
-                return (HSSPrivateKeyParameters)src;
+                return hssPrivateKeyParameters;
             }
-            else if (src is BinaryReader)
+            else if (src is BinaryReader binaryReader)
             {
-                byte[] data = ((BinaryReader) src).ReadBytes(4);
+                byte[] data = binaryReader.ReadBytes(4);
                 Array.Reverse(data);
                 int version = BitConverter.ToInt32(data, 0);
                 if (version != 0)
                 {
                     throw new Exception("unknown version for hss private key");
                 }
-                data = ((BinaryReader) src).ReadBytes(4);
+                data = binaryReader.ReadBytes(4);
                 Array.Reverse(data);
                 int d = BitConverter.ToInt32(data, 0);
                 
-                data = ((BinaryReader) src).ReadBytes(8);
+                data = binaryReader.ReadBytes(8);
                 Array.Reverse(data);
                 long index = BitConverter.ToInt64(data, 0);
                 
-                data = ((BinaryReader) src).ReadBytes(8);
+                data = binaryReader.ReadBytes(8);
                 Array.Reverse(data);
                 long maxIndex = BitConverter.ToInt64(data, 0);;
                 
-                data = ((BinaryReader) src).ReadBytes(1);
+                data = binaryReader.ReadBytes(1);
                 Array.Reverse(data);
-                bool limited =  BitConverter.ToBoolean(data, 0);
-                
+                bool limited = BitConverter.ToBoolean(data, 0);
 
                 var keys = new List<LMSPrivateKeyParameters>();
                 var signatures = new List<LMSSignature>();
@@ -110,12 +107,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
                 return new HSSPrivateKeyParameters(d, keys, signatures, index, maxIndex, limited);
             }
-            else if (src is byte[])
+            else if (src is byte[] bytes)
             {
                 BinaryReader input = null;
                 try // 1.5 / 1.6 compatibility
                 {
-                    input = new BinaryReader(new MemoryStream((byte[])src));
+                    input = new BinaryReader(new MemoryStream(bytes));
                     return GetInstance(input);
                 }
                 finally
@@ -126,9 +123,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                     }
                 }
             }
-            else if (src is MemoryStream)
+            else if (src is MemoryStream memoryStream)
             {
-                return GetInstance(Streams.ReadAll((Stream)src));
+                return GetInstance(Streams.ReadAll(memoryStream));
             }
 
             throw new Exception($"cannot parse {src}");
@@ -152,7 +149,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
                 for (int i = 0; i < len; i++)
                 {
-                    LMSPrivateKeyParameters lmsPrivateKey = (LMSPrivateKeyParameters) keys[i];
+                    LMSPrivateKeyParameters lmsPrivateKey = keys[i];
 
                     parms[i] = new LMSParameters(lmsPrivateKey.GetSigParameters(), lmsPrivateKey.GetOtsParameters());
                 }
@@ -171,14 +168,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
         private static HSSPrivateKeyParameters MakeCopy(HSSPrivateKeyParameters privateKeyParameters)
         {
-            try
-            {
-                return HSSPrivateKeyParameters.GetInstance(privateKeyParameters.GetEncoded());
-            }
-            catch (Exception ex)
-            {
-                throw new Exception(ex.Message, ex);
-            }
+            return GetInstance(privateKeyParameters.GetEncoded());
         }
 
         protected void UpdateHierarchy(IList<LMSPrivateKeyParameters> newKeys, IList<LMSSignature> newSig)
@@ -204,7 +194,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
         LMSPrivateKeyParameters GetRootKey()
         {
-            return keys[0] as LMSPrivateKeyParameters;
+            return keys[0];
         }
 
         /**
@@ -227,15 +217,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                 long shardStartIndex = index;
 
                 //
-                // Move this keys index along
+                // Move this key's index along
                 //
                 index += usageCount;
 
                 var keys = new List<LMSPrivateKeyParameters>(this.GetKeys());
                 var sig = new List<LMSSignature>(this.GetSig());
 
-                HSSPrivateKeyParameters shard = MakeCopy(new HSSPrivateKeyParameters(l, keys, sig, shardStartIndex,
-                    maxIndexForShard, true));
+                HSSPrivateKeyParameters shard = MakeCopy(
+                    new HSSPrivateKeyParameters(l, keys, sig, shardStartIndex, maxIndexForShard, true));
 
                 ResetKeyToIndex();
 
@@ -243,21 +233,14 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             }
         }
 
-
         public IList<LMSPrivateKeyParameters> GetKeys()
         {
-            lock (this)
-            {
-                return keys;
-            }
+            lock (this) return keys;
         }
 
-        internal IList<LMSSignature>GetSig()
+        internal IList<LMSSignature> GetSig()
         {
-            lock (this)
-            {
-                return sig;
-            }
+            lock (this) return sig;
         }
 
         /**
@@ -271,32 +254,29 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             // Extract the original keys
             var originalKeys = GetKeys();
 
-
             long[] qTreePath = new long[originalKeys.Count];
             long q = GetIndex();
 
             for (int t = originalKeys.Count - 1; t >= 0; t--)
             {
-                LMSigParameters sigParameters = (originalKeys[t] as LMSPrivateKeyParameters).GetSigParameters();
-                int mask = (1 << sigParameters.GetH()) - 1;
+                LMSigParameters sigParameters = originalKeys[t].GetSigParameters();
+                int mask = (1 << sigParameters.H) - 1;
                 qTreePath[t] = q & mask;
-                q >>= sigParameters.GetH();
+                q >>= sigParameters.H;
             }
 
             bool changed = false;
-            
-            
+
             // LMSPrivateKeyParameters[] keys =  originalKeys.ToArray(new LMSPrivateKeyParameters[originalKeys.Count]);//  new LMSPrivateKeyParameters[originalKeys.Size()];
             // LMSSignature[] sig = this.sig.toArray(new LMSSignature[this.sig.Count]);//   new LMSSignature[originalKeys.Size() - 1];
             //
-            
-            LMSPrivateKeyParameters originalRootKey = this.GetRootKey();
 
+            LMSPrivateKeyParameters originalRootKey = this.GetRootKey();
 
             //
             // We need to replace the root key to a new q value.
             //
-            if (((LMSPrivateKeyParameters)keys[0]).GetIndex() - 1 != qTreePath[0])
+            if (keys[0].GetIndex() - 1 != qTreePath[0])
             {
                 keys[0] = LMS.GenerateKeys(
                     originalRootKey.GetSigParameters(),
@@ -305,24 +285,24 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                 changed = true;
             }
 
-
             for (int i = 1; i < qTreePath.Length; i++)
             {
-
-                LMSPrivateKeyParameters intermediateKey = keys[i - 1] as LMSPrivateKeyParameters;
+                LMSPrivateKeyParameters intermediateKey = keys[i - 1];
 
                 byte[] childI = new byte[16];
                 byte[] childSeed = new byte[32];
                 SeedDerive derive = new SeedDerive(
                     intermediateKey.GetI(),
                     intermediateKey.GetMasterSecret(),
-                    DigestUtilities.GetDigest(intermediateKey.GetOtsParameters().GetDigestOid()));
-                derive.SetQ((int)qTreePath[i - 1]);
-                derive.SetJ(~1);
+                    DigestUtilities.GetDigest(intermediateKey.GetOtsParameters().DigestOid))
+                {
+                    Q = (int)qTreePath[i - 1],
+                    J = ~1,
+                };
 
-                derive.deriveSeed(childSeed, true);
+                derive.DeriveSeed(true, childSeed, 0);
                 byte[] postImage = new byte[32];
-                derive.deriveSeed(postImage, false);
+                derive.DeriveSeed(false, postImage, 0);
                 Array.Copy(postImage, 0, childI, 0, childI.Length);
 
                 //
@@ -330,16 +310,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                 // For intermediate keys they will always be out by one from the derived q value (qValues[i])
                 // For the end key its value will match so no correction is required.
                 //
-                bool lmsQMatch =
-                    (i < qTreePath.Length - 1) ? qTreePath[i] == ((LMSPrivateKeyParameters)keys[i]).GetIndex() - 1 : qTreePath[i] == ((LMSPrivateKeyParameters)keys[i]).GetIndex();
+                bool lmsQMatch = (i < qTreePath.Length - 1)
+                    ? qTreePath[i] == keys[i].GetIndex() - 1
+                    : qTreePath[i] == keys[i].GetIndex();
 
                 //
                 // Equality is I and seed being equal and the lmsQMath.
                 // I and seed are derived from this nodes parent and will change if the parent q, I, seed changes.
                 //
-                bool seedEquals = Arrays.AreEqual(childI, ((LMSPrivateKeyParameters)keys[i]).GetI())
-                    && Arrays.AreEqual(childSeed, ((LMSPrivateKeyParameters)keys[i]).GetMasterSecret());
-
+                bool seedEquals = Arrays.AreEqual(childI, keys[i].GetI())
+                    && Arrays.AreEqual(childSeed, keys[i].GetMasterSecret());
 
                 if (!seedEquals)
                 {
@@ -347,8 +327,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                     // This means the parent has changed.
                     //
                     keys[i] = LMS.GenerateKeys(
-                        ((LMSPrivateKeyParameters)originalKeys[i]).GetSigParameters(),
-                        ((LMSPrivateKeyParameters)originalKeys[i]).GetOtsParameters(),
+                        originalKeys[i].GetSigParameters(),
+                        originalKeys[i].GetOtsParameters(),
                         (int)qTreePath[i], childI, childSeed);
 
                     //
@@ -359,27 +339,23 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                 }
                 else if (!lmsQMatch)
                 {
-
                     //
                     // Q is different so we can generate a new private key but it will have the same public
                     // key so we do not need to sign it again.
                     //
                     keys[i] = LMS.GenerateKeys(
-                        ((LMSPrivateKeyParameters)originalKeys[i]).GetSigParameters(),
-                        ((LMSPrivateKeyParameters)originalKeys[i]).GetOtsParameters(),
+                        originalKeys[i].GetSigParameters(),
+                        originalKeys[i].GetOtsParameters(),
                         (int)qTreePath[i], childI, childSeed);
                     changed = true;
                 }
-
             }
 
-
             if (changed)
             {
                 // We mutate the HSS key here!
                 UpdateHierarchy(keys, sig);
             }
-
         }
 
         public HSSPublicKeyParameters GetPublicKey()
@@ -390,13 +366,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
         internal void ReplaceConsumedKey(int d)
         {
-
-            SeedDerive deriver = (keys[d - 1] as LMSPrivateKeyParameters).GetCurrentOtsKey().GetDerivationFunction();
-            deriver.SetJ(~1);
+            SeedDerive deriver = keys[d - 1].GetCurrentOtsKey().GetDerivationFunction();
+            deriver.J = ~1;
             byte[] childRootSeed = new byte[32];
-            deriver.deriveSeed(childRootSeed, true);
+            deriver.DeriveSeed(true, childRootSeed, 0);
             byte[] postImage = new byte[32];
-            deriver.deriveSeed(postImage, false);
+            deriver.DeriveSeed(false, postImage, 0);
             byte[] childI = new byte[16];
             Array.Copy(postImage, 0, childI, 0, childI.Length);
 
@@ -405,15 +380,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             //
             // We need the parameters from the LMS key we are replacing.
             //
-            LMSPrivateKeyParameters oldPk = keys[d] as LMSPrivateKeyParameters;
-
+            LMSPrivateKeyParameters oldPk = keys[d];
 
             newKeys[d] = LMS.GenerateKeys(oldPk.GetSigParameters(), oldPk.GetOtsParameters(), 0, childI, childRootSeed);
 
             var newSig = new List<LMSSignature>(sig);
 
-            newSig[d - 1] = LMS.GenerateSign(newKeys[d - 1] as LMSPrivateKeyParameters,
-                (newKeys[d] as LMSPrivateKeyParameters).GetPublicKey().ToByteArray());
+            newSig[d - 1] = LMS.GenerateSign(newKeys[d - 1], newKeys[d].GetPublicKey().ToByteArray());
 
             this.keys = new List<LMSPrivateKeyParameters>(newKeys);
             this.sig = new List<LMSSignature>(newSig);
@@ -481,7 +454,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                     .U32Str(l)
                     .U64Str(index)
                     .U64Str(indexLimit)
-                    .GetBool(isShard); // Depth
+                    .Boolean(isShard); // Depth
 
                 foreach (LMSPrivateKeyParameters key in keys)
                 {
@@ -508,7 +481,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             return result;
         }
 
-        protected Object Clone()
+        protected object Clone()
         {
             return MakeCopy(this);
         }
@@ -526,17 +499,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                 var keys = this.GetKeys();
                 var sig = this.GetSig();
 
-                nextKey = this.GetKeys()[(L - 1)] as LMSPrivateKeyParameters;
+                nextKey = this.GetKeys()[L - 1];
 
                 // Step 2. Stand in for sig[L-1]
                 int i = 0;
                 signed_pub_key = new LMSSignedPubKey[L - 1];
                 while (i < L - 1)
                 {
-                    signed_pub_key[i] = new LMSSignedPubKey(
-                        sig[i] as LMSSignature,
-                        (keys[i + 1] as LMSPrivateKeyParameters).GetPublicKey());
-                    i = i + 1;
+                    signed_pub_key[i] = new LMSSignedPubKey(sig[i], keys[i + 1].GetPublicKey());
+                    ++i;
                 }
 
                 //
@@ -560,4 +531,4 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/HSSPublicKeyParameters.cs b/crypto/src/pqc/crypto/lms/HSSPublicKeyParameters.cs
index d833e674a..f6641d9c1 100644
--- a/crypto/src/pqc/crypto/lms/HSSPublicKeyParameters.cs
+++ b/crypto/src/pqc/crypto/lms/HSSPublicKeyParameters.cs
@@ -1,43 +1,43 @@
 using System;
 using System.IO;
+
 using Org.BouncyCastle.Utilities.IO;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-    public class HSSPublicKeyParameters
+    public sealed class HSSPublicKeyParameters
         : LMSKeyParameters, ILMSContextBasedVerifier
     {
-        private int l;
-        private LMSPublicKeyParameters lmsPublicKey;
+        private readonly int m_l;
+        private readonly LMSPublicKeyParameters m_lmsPublicKey;
 
         public HSSPublicKeyParameters(int l, LMSPublicKeyParameters lmsPublicKey)
     	    :base(false)
         {
-
-            this.l = l;
-            this.lmsPublicKey = lmsPublicKey;
+            m_l = l;
+            m_lmsPublicKey = lmsPublicKey;
         }
 
-        public static HSSPublicKeyParameters GetInstance(Object src)
+        public static HSSPublicKeyParameters GetInstance(object src)
         {
-            if (src is HSSPublicKeyParameters)
+            if (src is HSSPublicKeyParameters hssPublicKeyParameters)
             {
-                return (HSSPublicKeyParameters)src;
+                return hssPublicKeyParameters;
             }
-            else if (src is BinaryReader)
+            else if (src is BinaryReader binaryReader)
             {
-                byte[] data = ((BinaryReader) src).ReadBytes(4);
+                byte[] data = binaryReader.ReadBytes(4);
                 Array.Reverse(data);
                 int L = BitConverter.ToInt32(data, 0);
                 LMSPublicKeyParameters lmsPublicKey = LMSPublicKeyParameters.GetInstance(src);// todo check endianness
                 return new HSSPublicKeyParameters(L, lmsPublicKey);
             }
-            else if (src is byte[])
+            else if (src is byte[] bytes)
             {
                 BinaryReader input = null;
                 try // 1.5 / 1.6 compatibility
                 {
-                    input = new BinaryReader(new MemoryStream((byte[])src));
+                    input = new BinaryReader(new MemoryStream(bytes));
                     return GetInstance(input);
                 }
                 finally
@@ -45,55 +45,42 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                     if (input != null) input.Close();
                 }
             }
-            else if (src is MemoryStream)
+            else if (src is MemoryStream memoryStream)
             {
-                return GetInstance(Streams.ReadAll((Stream)src));
+                return GetInstance(Streams.ReadAll(memoryStream));
             }
 
             throw new ArgumentException($"cannot parse {src}");
         }
 
-        public int GetL()
-        {
-            return l;
-        }
+        public int L => m_l;
+
+        public LMSPublicKeyParameters LmsPublicKey => m_lmsPublicKey;
 
-        public LMSPublicKeyParameters GetLmsPublicKey()
-        {
-            return lmsPublicKey;
-        }
-        
         public override bool Equals(Object o)
         {
             if (this == o)
-            {
                 return true;
-            }
             if (o == null || GetType() != o.GetType())
-            {
                 return false;
-            }
 
             HSSPublicKeyParameters publicKey = (HSSPublicKeyParameters)o;
 
-            if (l != publicKey.l)
-            {
-                return false;
-            }
-            return lmsPublicKey.Equals(publicKey.lmsPublicKey);
+            return m_l == publicKey.m_l
+                && m_lmsPublicKey.Equals(publicKey.m_lmsPublicKey);
         }
 
         public override int GetHashCode()
         {
-            int result = l;
-            result = 31 * result + lmsPublicKey.GetHashCode();
+            int result = m_l;
+            result = 31 * result + m_lmsPublicKey.GetHashCode();
             return result;
         }
 
         public override byte[] GetEncoded()
         {
-            return Composer.Compose().U32Str(l)
-                .Bytes(lmsPublicKey.GetEncoded())
+            return Composer.Compose().U32Str(m_l)
+                .Bytes(m_lmsPublicKey.GetEncoded())
                 .Build();
         }
 
@@ -102,31 +89,28 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             HSSSignature signature;
             try
             {
-                signature = HSSSignature.GetInstance(sigEnc, GetL());
+                signature = HSSSignature.GetInstance(sigEnc, L);
             }
             catch (IOException e)
             {
                 throw new Exception($"cannot parse signature: {e.Message}");
             }
 
-            LMSSignedPubKey[] signedPubKeys = signature.GetSignedPubKey();
+            LMSSignedPubKey[] signedPubKeys = signature.GetSignedPubKeys();
             LMSPublicKeyParameters key = signedPubKeys[signedPubKeys.Length - 1].GetPublicKey();
 
-            return key.GenerateOtsContext(signature.GetSignature()).WithSignedPublicKeys(signedPubKeys);
+            return key.GenerateOtsContext(signature.Signature).WithSignedPublicKeys(signedPubKeys);
         }
 
         public bool Verify(LMSContext context)
         {
-            bool failed = false;
+            LMSSignedPubKey[] sigKeys = context.SignedPubKeys;
 
-            LMSSignedPubKey[] sigKeys = context.GetSignedPubKeys();
-
-            if (sigKeys.Length != GetL() - 1)
-            {
+            if (sigKeys.Length != L - 1)
                 return false;
-            }
 
-            LMSPublicKeyParameters key = GetLmsPublicKey();
+            LMSPublicKeyParameters key = LmsPublicKey;
+            bool failed = false;
 
             for (int i = 0; i < sigKeys.Length; i++)
             {
diff --git a/crypto/src/pqc/crypto/lms/HSSSignature.cs b/crypto/src/pqc/crypto/lms/HSSSignature.cs
index 022ae7de3..793beda66 100644
--- a/crypto/src/pqc/crypto/lms/HSSSignature.cs
+++ b/crypto/src/pqc/crypto/lms/HSSSignature.cs
@@ -1,13 +1,11 @@
-
 using System;
 using System.IO;
-using Org.BouncyCastle.Pqc.Crypto.Lms;
+
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.IO;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-
     public class HSSSignature
         : IEncodable
     {
@@ -31,19 +29,17 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
      */
         public static HSSSignature GetInstance(Object src, int L)
         {
-            if (src is HSSSignature)
+            if (src is HSSSignature hssSignature)
             {
-                return (HSSSignature) src;
+                return hssSignature;
             }
-            else if (src is BinaryReader)
+            else if (src is BinaryReader binaryReader)
             {
-                byte[] data = ((BinaryReader) src).ReadBytes(4);
+                byte[] data = binaryReader.ReadBytes(4);
                 Array.Reverse(data);
                 int lminus = BitConverter.ToInt32(data, 0);
                 if (lminus != L - 1)
-                {
                     throw new Exception("nspk exceeded maxNspk");
-                }
 
                 LMSSignedPubKey[] signedPubKeys = new LMSSignedPubKey[lminus];
                 if (lminus != 0)
@@ -59,12 +55,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
                 return new HSSSignature(lminus, signedPubKeys, sig);
             }
-            else if (src is byte[])
+            else if (src is byte[] bytes)
             {
                 BinaryReader input = null;
                 try // 1.5 / 1.6 compatibility
                 {
-                    input = new BinaryReader(new MemoryStream((byte[]) src));
+                    input = new BinaryReader(new MemoryStream(bytes));
                     return GetInstance(input, L);
                 }
                 finally
@@ -72,29 +68,26 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                     if (input != null) input.Close();
                 }
             }
-            else if (src is MemoryStream)
+            else if (src is MemoryStream memoryStream)
             {
-                return GetInstance(Streams.ReadAll((Stream) src), L);
+                return GetInstance(Streams.ReadAll(memoryStream), L);
             }
 
             throw new ArgumentException($"cannot parse {src}");
         }
 
-
+        // FIXME
         public int GetlMinus1()
         {
             return lMinus1;
         }
 
-        public LMSSignedPubKey[] GetSignedPubKey()
+        public LMSSignedPubKey[] GetSignedPubKeys()
         {
             return signedPubKey;
         }
 
-        public LMSSignature GetSignature()
-        {
-            return signature;
-        }
+        public LMSSignature Signature => signature;
 
         public override bool Equals(Object o)
         {
@@ -114,6 +107,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             {
                 return false;
             }
+
+            // FIXME
             // Probably incorrect - comparing Object[] arrays with Arrays.equals
 
             if (signedPubKey.Length != signature1.signedPubKey.Length)
diff --git a/crypto/src/pqc/crypto/lms/HSSSigner.cs b/crypto/src/pqc/crypto/lms/HSSSigner.cs
index 9f361d20b..4bbdff848 100644
--- a/crypto/src/pqc/crypto/lms/HSSSigner.cs
+++ b/crypto/src/pqc/crypto/lms/HSSSigner.cs
@@ -39,7 +39,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         {
             try
             {
-                return HSS.VerifySignature(pubKey, HSSSignature.GetInstance(signature, pubKey.GetL()), message);
+                return HSS.VerifySignature(pubKey, HSSSignature.GetInstance(signature, pubKey.L), message);
             }
             catch (IOException e)
             {
diff --git a/crypto/src/pqc/crypto/lms/LMOtsParameters.cs b/crypto/src/pqc/crypto/lms/LMOtsParameters.cs
index ca237fc5e..f3107d31d 100644
--- a/crypto/src/pqc/crypto/lms/LMOtsParameters.cs
+++ b/crypto/src/pqc/crypto/lms/LMOtsParameters.cs
@@ -1,86 +1,65 @@
-using System;
 using System.Collections.Generic;
+
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-    public class LMOtsParameters
+    public sealed class LMOtsParameters
     {
-        //TODO add all parameter sets
+        // TODO add all parameter sets
 
-        public static int reserved = 0;
+        //public static int reserved = 0;
         public static LMOtsParameters sha256_n32_w1 = new LMOtsParameters(1, 32, 1, 265, 7, 8516, NistObjectIdentifiers.IdSha256);
         public static LMOtsParameters sha256_n32_w2 = new LMOtsParameters(2, 32, 2, 133, 6, 4292, NistObjectIdentifiers.IdSha256);
         public static LMOtsParameters sha256_n32_w4 = new LMOtsParameters(3, 32, 4, 67, 4, 2180, NistObjectIdentifiers.IdSha256);
         public static LMOtsParameters sha256_n32_w8 = new LMOtsParameters(4, 32, 8, 34, 0, 1124, NistObjectIdentifiers.IdSha256);
 
-        private static Dictionary<Object, LMOtsParameters> suppliers = new Dictionary<object, LMOtsParameters>
+        private static Dictionary<object, LMOtsParameters> Suppliers = new Dictionary<object, LMOtsParameters>
         {
-            { sha256_n32_w1.type, sha256_n32_w1 },
-            { sha256_n32_w2.type, sha256_n32_w2 },
-            { sha256_n32_w4.type, sha256_n32_w4 },
-            { sha256_n32_w8.type, sha256_n32_w8 }
+            { sha256_n32_w1.ID, sha256_n32_w1 },
+            { sha256_n32_w2.ID, sha256_n32_w2 },
+            { sha256_n32_w4.ID, sha256_n32_w4 },
+            { sha256_n32_w8.ID, sha256_n32_w8 }
         };
-        
-        
-        private int type;
-        private int n;
-        private int w;
-        private int p;
-        private int ls;
-        private uint sigLen;
-        private DerObjectIdentifier digestOID;
 
-        protected LMOtsParameters(int type, int n, int w, int p, int ls, uint sigLen, DerObjectIdentifier digestOID)
-        {
-            this.type = type;
-            this.n = n;
-            this.w = w;
-            this.p = p;
-            this.ls = ls;
-            this.sigLen = sigLen;
-            this.digestOID = digestOID;
-        }
-        public new int GetType()
-        {
-            return type;
-        }
+        private readonly int m_id;
+        private readonly int m_n;
+        private readonly int m_w;
+        private readonly int m_p;
+        private readonly int m_ls;
+        private readonly uint m_sigLen;
+        private readonly DerObjectIdentifier m_digestOid;
 
-        public int GetN()
+        protected LMOtsParameters(int id, int n, int w, int p, int ls, uint sigLen, DerObjectIdentifier digestOid)
         {
-            return n;
+            m_id = id;
+            m_n = n;
+            m_w = w;
+            m_p = p;
+            m_ls = ls;
+            m_sigLen = sigLen;
+            m_digestOid = digestOid;
         }
 
-        public int GetW()
-        {
-            return w;
-        }
+        public int ID => m_id;
 
-        public int GetP()
-        {
-            return p;
-        }
+        public int N => m_n;
 
-        public int GetLs()
-        {
-            return ls;
-        }
+        public int W => m_w;
 
-        public uint GetSigLen()
-        {
-            return sigLen;
-        }
+        public int P => m_p;
 
-        public DerObjectIdentifier GetDigestOid()
-        {
-            return digestOID;
-        }
+        public int Ls => m_ls;
+
+        public uint SigLen => m_sigLen;
 
-        public static LMOtsParameters GetParametersForType(int type)
+        public DerObjectIdentifier DigestOid => m_digestOid;
+
+        public static LMOtsParameters GetParametersByID(int id)
         {
-            return suppliers[type];
+            return CollectionUtilities.GetValueOrNull(Suppliers, id);
         }
-
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/LMOtsPrivateKey.cs b/crypto/src/pqc/crypto/lms/LMOtsPrivateKey.cs
index e5ed9d7b0..8482c1a53 100644
--- a/crypto/src/pqc/crypto/lms/LMOtsPrivateKey.cs
+++ b/crypto/src/pqc/crypto/lms/LMOtsPrivateKey.cs
@@ -1,38 +1,36 @@
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Security;
 
-using static Org.BouncyCastle.Pqc.Crypto.Lms.LM_OTS;
-
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-    public class LMOtsPrivateKey
+    public sealed class LMOtsPrivateKey
     {
-        private LMOtsParameters parameter;
-        private byte[] I;
-        private int q;
-        private byte[] masterSecret;
+        private readonly LMOtsParameters m_parameters;
+        private readonly byte[] m_I;
+        private readonly int m_q;
+        private readonly byte[] m_masterSecret;
 
-        public LMOtsPrivateKey(LMOtsParameters parameter, byte[] i, int q, byte[] masterSecret)
+        public LMOtsPrivateKey(LMOtsParameters parameters, byte[] i, int q, byte[] masterSecret)
         {
-            this.parameter = parameter;
-            I = i;
-            this.q = q;
-            this.masterSecret = masterSecret;
+            m_parameters = parameters;
+            m_I = i;
+            m_q = q;
+            m_masterSecret = masterSecret;
         }
 
         public LMSContext GetSignatureContext(LMSigParameters sigParams, byte[][] path)
         {
-            byte[] C = new byte[SEED_LEN];
+            byte[] C = new byte[LM_OTS.SEED_LEN];
 
             SeedDerive derive = GetDerivationFunction();
-            derive.SetJ(SEED_RANDOMISER_INDEX); // This value from reference impl.
-            derive.deriveSeed(C, false);
+            derive.J = LM_OTS.SEED_RANDOMISER_INDEX; // This value from reference impl.
+            derive.DeriveSeed(false, C, 0);
 
-            IDigest ctx = DigestUtilities.GetDigest(parameter.GetDigestOid());
+            IDigest ctx = DigestUtilities.GetDigest(m_parameters.DigestOid);
 
-            LmsUtils.ByteArray(this.GetI(), ctx);
-            LmsUtils.U32Str(this.GetQ(), ctx);
-            LmsUtils.U16Str(D_MESG, ctx);
+            LmsUtils.ByteArray(m_I, ctx);
+            LmsUtils.U32Str(m_q, ctx);
+            LmsUtils.U16Str(LM_OTS.D_MESG, ctx);
             LmsUtils.ByteArray(C, ctx);
 
             return new LMSContext(this, sigParams, ctx, C, path);
@@ -40,30 +38,21 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
         internal SeedDerive GetDerivationFunction()
         {
-            SeedDerive derive = new SeedDerive(I, masterSecret, DigestUtilities.GetDigest(parameter.GetDigestOid()));
-            derive.SetQ(q);
-            return derive;
+            return new SeedDerive(m_I, m_masterSecret, DigestUtilities.GetDigest(m_parameters.DigestOid))
+            {
+                Q = m_q,
+                J = 0,
+            };
         }
 
+        public LMOtsParameters Parameters => m_parameters;
 
-        public LMOtsParameters GetParameter()
-        {
-            return parameter;
-        }
-
-        public byte[] GetI()
-        {
-            return I;
-        }
+        // FIXME
+        public byte[] I => m_I;
 
-        public int GetQ()
-        {
-            return q;
-        }
+        public int Q => m_q;
 
-        public byte[] GetMasterSecret()
-        {
-            return masterSecret;
-        }
+        // FIXME
+        public byte[] MasterSecret => m_masterSecret;
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/LMOtsPublicKey.cs b/crypto/src/pqc/crypto/lms/LMOtsPublicKey.cs
index c3d1794ff..49c0871f5 100644
--- a/crypto/src/pqc/crypto/lms/LMOtsPublicKey.cs
+++ b/crypto/src/pqc/crypto/lms/LMOtsPublicKey.cs
@@ -1,63 +1,60 @@
 using System;
 using System.IO;
+
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.IO;
 
-using static Org.BouncyCastle.Pqc.Crypto.Lms.LM_OTS;
-
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-    public class LMOtsPublicKey
+    public sealed class LMOtsPublicKey
     {
-        private LMOtsParameters parameter;
-        private byte[] I;
-        private int q;
-        private byte[] K;
+        private readonly LMOtsParameters m_parameters;
+        private readonly byte[] m_I;
+        private readonly int m_q;
+        private readonly byte[] m_K;
 
-
-        public LMOtsPublicKey(LMOtsParameters parameter, byte[] i, int q, byte[] k)
+        public LMOtsPublicKey(LMOtsParameters parameters, byte[] i, int q, byte[] k)
         {
-            this.parameter = parameter;
-            this.I = i;
-            this.q = q;
-            this.K = k;
+            m_parameters = parameters;
+            m_I = i;
+            m_q = q;
+            m_K = k;
         }
 
-        public static LMOtsPublicKey GetInstance(Object src)
+        public static LMOtsPublicKey GetInstance(object src)
         {
-            
             //todo
-            if (src is LMOtsPublicKey)
+            if (src is LMOtsPublicKey lmOtsPublicKey)
             {
-                return (LMOtsPublicKey)src;
+                return lmOtsPublicKey;
             }
-            else if (src is BinaryReader)
+            else if (src is BinaryReader binaryReader)
             {
-                byte[] data = ((BinaryReader) src).ReadBytes(4);
+                byte[] data = binaryReader.ReadBytes(4);
                 Array.Reverse(data);
                 int index = BitConverter.ToInt32(data, 0);
                 
-                LMOtsParameters parameter = LMOtsParameters.GetParametersForType(index);
+                LMOtsParameters parameter = LMOtsParameters.GetParametersByID(index);
                 byte[] I = new byte[16];
-                ((BinaryReader)src).Read(I, 0, I.Length);
+                binaryReader.Read(I, 0, I.Length);
                 
                 Array.Reverse(data);
                 int q = BitConverter.ToInt32(data, 0);
 
-                byte[] K = new byte[parameter.GetN()];
-                ((BinaryReader)src).Read(K, 0, K.Length);
+                byte[] K = new byte[parameter.N];
+                binaryReader.Read(K, 0, K.Length);
 
                 return new LMOtsPublicKey(parameter, I, q, K);
 
             }
-            else if (src is byte[])
+            else if (src is byte[] bytes)
             {
                 BinaryReader input = null;
                 try // 1.5 / 1.6 compatibility
                 {
-                    input = new BinaryReader(new MemoryStream((byte[])src, false));
+                    input = new BinaryReader(new MemoryStream(bytes, false));
                     return GetInstance(input);
                 }
                 finally
@@ -65,102 +62,75 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                     if (input != null) input.Close();//todo Platform Dispose
                 }
             }
-            else if (src is MemoryStream)
+            else if (src is MemoryStream memoryStream)
             {
-                return GetInstance(Streams.ReadAll((Stream)src));
+                return GetInstance(Streams.ReadAll(memoryStream));
             }
             throw new Exception ($"cannot parse {src}");
         }
 
-        public LMOtsParameters GetParameter()
-        {
-            return parameter;
-        }
+        public LMOtsParameters Parameters => m_parameters;
 
-        public byte[] GetI()
-        {
-            return I;
-        }
+        public byte[] I => m_I;
 
-        public int GetQ()
-        {
-            return q;
-        }
+        public int Q => m_q;
 
-        public byte[] GetK()
-        {
-            return K;
-        }
+        public byte[] K => m_K;
 
-        public override bool Equals(Object o)
+        public override bool Equals(object obj)
         {
-            if (this == o)
-            {
+            if (this == obj)
                 return true;
-            }
-            if (o == null || GetType() != o.GetType())
-            {
+            if (!(obj is LMOtsPublicKey that))
                 return false;
-            }
-
-            LMOtsPublicKey that = (LMOtsPublicKey)o;
 
-            if (q != that.q)
-            {
-                return false;
-            }
-            if (!parameter?.Equals(that.parameter) ?? that.parameter != null)
-            {
-                return false;
-            }
-            if (!Arrays.Equals(I, that.I))
-            {
-                return false;
-            }
-            return Arrays.Equals(K, that.K);
+            return m_q == that.m_q
+                && Objects.Equals(m_parameters, that.m_parameters)
+                && Arrays.AreEqual(m_I, that.m_I)
+                && Arrays.AreEqual(m_K, that.m_K);
         }
 
         public override int GetHashCode()
         {
-            int result = parameter != null ? parameter.GetHashCode() : 0;
-            result = 31 * result + Arrays.GetHashCode(I);
-            result = 31 * result + q;
-            result = 31 * result + Arrays.GetHashCode(K);
+            int result = Objects.GetHashCode(m_parameters);
+            result = 31 * result + Arrays.GetHashCode(m_I);
+            result = 31 * result + m_q;
+            result = 31 * result + Arrays.GetHashCode(m_K);
             return result;
         }
 
         public byte[] GetEncoded()
         {
             return Composer.Compose()
-                .U32Str(parameter.GetType())
-                .Bytes(I)
-                .U32Str(q)
-                .Bytes(K)
+                .U32Str(m_parameters.ID)
+                .Bytes(m_I)
+                .U32Str(m_q)
+                .Bytes(m_K)
                 .Build();
         }
 
         internal LMSContext CreateOtsContext(LMOtsSignature signature)
         {
-            IDigest ctx = DigestUtilities.GetDigest(parameter.GetDigestOid());
+            IDigest ctx = DigestUtilities.GetDigest(m_parameters.DigestOid);
 
-            LmsUtils.ByteArray(I, ctx);
-            LmsUtils.U32Str(q, ctx);
-            LmsUtils.U16Str(D_MESG, ctx);
-            LmsUtils.ByteArray(signature.GetC(), ctx);
+            LmsUtils.ByteArray(m_I, ctx);
+            LmsUtils.U32Str(m_q, ctx);
+            LmsUtils.U16Str(LM_OTS.D_MESG, ctx);
+            LmsUtils.ByteArray(signature.C, ctx);
 
             return new LMSContext(this, signature, ctx);
         }
 
         internal LMSContext CreateOtsContext(LMSSignature signature)
         {
-            IDigest ctx = DigestUtilities.GetDigest(parameter.GetDigestOid());
+            IDigest ctx = DigestUtilities.GetDigest(m_parameters.DigestOid);
 
-            LmsUtils.ByteArray(I, ctx);
-            LmsUtils.U32Str(q, ctx);
-            LmsUtils.U16Str(D_MESG, ctx);
-            LmsUtils.ByteArray(signature.GetOtsSignature().GetC(), ctx);
+            LmsUtils.ByteArray(m_I, ctx);
+            LmsUtils.U32Str(m_q, ctx);
+            LmsUtils.U16Str(LM_OTS.D_MESG, ctx);
+            LmsUtils.ByteArray(signature.OtsSignature.C, ctx);
 
             return new LMSContext(this, signature, ctx);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/LMOtsSignature.cs b/crypto/src/pqc/crypto/lms/LMOtsSignature.cs
index 599255fbd..db4b25641 100644
--- a/crypto/src/pqc/crypto/lms/LMOtsSignature.cs
+++ b/crypto/src/pqc/crypto/lms/LMOtsSignature.cs
@@ -1,54 +1,54 @@
 using System;
 using System.IO;
+
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.IO;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-    public class LMOtsSignature
+    public sealed class LMOtsSignature
         : IEncodable
     {
-        private LMOtsParameters ParamType;
-        private byte[] C;
-        private byte[] y;
+        private readonly LMOtsParameters m_paramType;
+        private readonly byte[] m_C;
+        private readonly byte[] m_y;
 
         public LMOtsSignature(LMOtsParameters ParamType, byte[] c, byte[] y)
         {
-            this.ParamType = ParamType;
-            C = c;
-            this.y = y;
+            m_paramType = ParamType;
+            m_C = c;
+            m_y = y;
         }
 
-        public static LMOtsSignature GetInstance(Object src)
+        public static LMOtsSignature GetInstance(object src)
         {
-            if (src is LMOtsSignature)
+            if (src is LMOtsSignature lmOtsSignature)
             {
-                return (LMOtsSignature)src;
+                return lmOtsSignature;
             }
             //TODO replace inputstreams with something
             
-            else if (src is BinaryReader)
+            else if (src is BinaryReader binaryReader)
             {
-                byte[] data = ((BinaryReader) src).ReadBytes(4);
+                byte[] data = binaryReader.ReadBytes(4);
                 Array.Reverse(data);
                 int index = BitConverter.ToInt32(data, 0);
-                LMOtsParameters type = LMOtsParameters.GetParametersForType(index);
-                byte[] C = new byte[type.GetN()];
-            
-                ((BinaryReader)src).Read(C, 0, C.Length);
-            
-                byte[] sig = new byte[type.GetP()*type.GetN()];
-                ((BinaryReader)src).Read(sig, 0, sig.Length);
-            
+                LMOtsParameters type = LMOtsParameters.GetParametersByID(index);
+                byte[] C = new byte[type.N];
+
+                binaryReader.Read(C, 0, C.Length);
             
+                byte[] sig = new byte[type.P * type.N];
+                binaryReader.Read(sig, 0, sig.Length);
+
                 return new LMOtsSignature(type, C, sig);
             }
-            else if (src is byte[])
+            else if (src is byte[] bytes)
             {
                 BinaryReader input = null;
                 try // 1.5 / 1.4 compatibility
                 {
-                    input = new BinaryReader(new MemoryStream((byte[])src, false));
+                    input = new BinaryReader(new MemoryStream(bytes, false));
                     return GetInstance(input);
                 }
                 finally
@@ -56,65 +56,47 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                     if (input != null) input.Close();
                 }
             }
-            else if (src is MemoryStream)
+            else if (src is MemoryStream memoryStream)
             {
-                return GetInstance(Streams.ReadAll((Stream)src));
+                return GetInstance(Streams.ReadAll(memoryStream));
             }
             throw new Exception ($"cannot parse {src}");
         }
-        public LMOtsParameters GetParamType()
-        {
-            return ParamType;
-        }
 
-        public byte[] GetC()
-        {
-            return C;
-        }
+        public LMOtsParameters ParamType => m_paramType;
 
-        public byte[] GetY()
-        {
-            return y;
-        }
+        // FIXME
+        public byte[] C => m_C;
 
-        public override bool Equals(object o)
+        // FIXME
+        public byte[] Y => m_y;
+
+        public override bool Equals(object obj)
         {
-            if (this == o)
-            {
+            if (this == obj)
                 return true;
-            }
-            if (o == null || GetType() != o.GetType())
-            {
+            if (!(obj is LMOtsSignature that))
                 return false;
-            }
-
-            LMOtsSignature that = (LMOtsSignature)o;
 
-            if (ParamType != null ? !ParamType.Equals(that.ParamType) : that.ParamType != null)
-            {
-                return false;
-            }
-            if (!Arrays.AreEqual(C, that.C))
-            {
-                return false;
-            }
-            return Arrays.AreEqual(y, that.y);
+            return Objects.Equals(m_paramType, that.m_paramType)
+                && Arrays.AreEqual(m_C, that.m_C)
+                && Arrays.AreEqual(m_y, that.m_y);
         }
 
         public override int GetHashCode()
         {
-            int result = ParamType != null ? ParamType.GetHashCode() : 0;
-            result = 31 * result + Arrays.GetHashCode(C);
-            result = 31 * result + Arrays.GetHashCode(y);
+            int result = Objects.GetHashCode(m_paramType);
+            result = 31 * result + Arrays.GetHashCode(m_C);
+            result = 31 * result + Arrays.GetHashCode(m_y);
             return result;
         }
 
         public byte[] GetEncoded()
         {
             return Composer.Compose()
-                .U32Str(ParamType.GetType())
-                .Bytes(C)
-                .Bytes(y)
+                .U32Str(m_paramType.ID)
+                .Bytes(m_C)
+                .Bytes(m_y)
                 .Build();
         }
     }
diff --git a/crypto/src/pqc/crypto/lms/LMS.cs b/crypto/src/pqc/crypto/lms/LMS.cs
index e6f7f4dda..c2401bd35 100644
--- a/crypto/src/pqc/crypto/lms/LMS.cs
+++ b/crypto/src/pqc/crypto/lms/LMS.cs
@@ -1,11 +1,11 @@
-
 using System;
+
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Security;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-    public class LMS
+    public static class LMS
     {
         internal static ushort D_LEAF = 0x8282;
         internal static ushort D_INTR = 0x8383;
@@ -25,12 +25,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
 
             // Step 2
-            if (rootSeed == null || rootSeed.Length < parameterSet.GetM())
-            {
-                throw new ArgumentException($"root seed is less than {parameterSet.GetM()}");
-            }
+            if (rootSeed == null || rootSeed.Length < parameterSet.M)
+                throw new ArgumentException($"root seed is less than {parameterSet.M}");
 
-            int twoToH = 1 << parameterSet.GetH();
+            int twoToH = 1 << parameterSet.H;
 
             return new LMSPrivateKeyParameters(parameterSet, lmOtsParameters, q, I, twoToH, rootSeed);
         }
@@ -61,10 +59,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
             // Step 1.
             LMOtsSignature ots_signature =
-                LM_OTS.lm_ots_generate_signature(context.GetPrivateKey(), context.GetQ(), context.C);
+                LM_OTS.LMOtsGenerateSignature(context.PrivateKey, context.GetQ(), context.C);
 
-            return new LMSSignature(context.GetPrivateKey().GetQ(), ots_signature, context.GetSigParams(),
-                context.GetPath());
+            return new LMSSignature(context.PrivateKey.Q, ots_signature, context.SigParams, context.Path);
         }
 
         public static bool VerifySignature(LMSPublicKeyParameters publicKey, LMSSignature S, byte[] message)
@@ -87,18 +84,18 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
         public static bool VerifySignature(LMSPublicKeyParameters publicKey, LMSContext context)
         {
-            LMSSignature S = (LMSSignature) context.GetSignature();
-            LMSigParameters lmsParameter = S.GetParameter();
-            int h = lmsParameter.GetH();
-            byte[][] path = S.GetY();
-            byte[] Kc = LM_OTS.lm_ots_validate_signature_calculate(context);
+            LMSSignature S = (LMSSignature)context.Signature;
+            LMSigParameters lmsParameter = S.SigParameters;
+            int h = lmsParameter.H;
+            byte[][] path = S.Y;
+            byte[] Kc = LM_OTS.LMOtsValidateSignatureCalculate(context);
             // Step 4
             // node_num = 2^h + q
-            int node_num = (1 << h) + S.GetQ();
+            int node_num = (1 << h) + S.Q;
 
             // tmp = H(I || u32str(node_num) || u16str(D_LEAF) || Kc)
             byte[] I = publicKey.GetI();
-            IDigest H = DigestUtilities.GetDigest(lmsParameter.GetDigestOid());
+            IDigest H = DigestUtilities.GetDigest(lmsParameter.DigestOid);
             byte[] tmp = new byte[H.GetDigestSize()];
 
             H.BlockUpdate(I, 0, I.Length);
diff --git a/crypto/src/pqc/crypto/lms/LMSContext.cs b/crypto/src/pqc/crypto/lms/LMSContext.cs
index 2113184fe..12975b637 100644
--- a/crypto/src/pqc/crypto/lms/LMSContext.cs
+++ b/crypto/src/pqc/crypto/lms/LMSContext.cs
@@ -1,139 +1,108 @@
 using System;
-using Org.BouncyCastle.Crypto;
 
-using static Org.BouncyCastle.Pqc.Crypto.Lms.LM_OTS;
+using Org.BouncyCastle.Crypto;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-    public class LMSContext
+    public sealed class LMSContext
         : IDigest
     {
-        private byte[] c;
-        private LMOtsPrivateKey key;
-        private LMSigParameters sigParams;
-        private byte[][] path;
-        private LMOtsPublicKey publicKey;
-        private Object signature;
+        private readonly byte[] m_c;
+        private readonly LMOtsPrivateKey m_privateKey;
+        private readonly LMSigParameters m_sigParams;
+        private readonly byte[][] m_path;
 
-        private LMSSignedPubKey[] signedPubKeys;
-        private volatile IDigest digest;
+        private readonly LMOtsPublicKey m_publicKey;
+        private readonly object m_signature;
+        private LMSSignedPubKey[] m_signedPubKeys;
+        private volatile IDigest m_digest;
 
-        public LMSContext(LMOtsPrivateKey key, LMSigParameters sigParams, IDigest digest, byte[] C, byte[][] path)
+        public LMSContext(LMOtsPrivateKey privateKey, LMSigParameters sigParams, IDigest digest, byte[] C,
+            byte[][] path)
         {
-            this.key = key;
-            this.sigParams = sigParams;
-            this.digest = digest;
-            this.c = C;
-            this.path = path;
-            this.publicKey = null;
-            this.signature = null;
+            m_privateKey = privateKey;
+            m_sigParams = sigParams;
+            m_digest = digest;
+            m_c = C;
+            m_path = path;
+            m_publicKey = null;
+            m_signature = null;
         }
 
-        public LMSContext(LMOtsPublicKey publicKey, Object signature, IDigest digest)
+        public LMSContext(LMOtsPublicKey publicKey, object signature, IDigest digest)
         {
-            this.publicKey = publicKey;
-            this.signature = signature;
-            this.digest = digest;
-            this.c = null;
-            this.key = null;
-            this.sigParams = null;
-            this.path = null;
+            m_publicKey = publicKey;
+            m_signature = signature;
+            m_digest = digest;
+            m_c = null;
+            m_privateKey = null;
+            m_sigParams = null;
+            m_path = null;
         }
 
-        public byte[] C => c;
+        public byte[] C => m_c;
 
         public byte[] GetQ()
         {
-            byte[] Q = new byte[MAX_HASH + 2];
-
-            digest.DoFinal(Q, 0);
-            
-            digest = null;
-
+            byte[] Q = new byte[LM_OTS.MAX_HASH + 2];
+            m_digest.DoFinal(Q, 0);
+            m_digest = null;
             return Q;
         }
 
-        internal byte[][] GetPath()
-        {
-            return path;
-        }
+        internal byte[][] Path => m_path;
 
-        internal LMOtsPrivateKey GetPrivateKey()
-        {
-            return key;
-        }
+        internal LMOtsPrivateKey PrivateKey => m_privateKey;
 
-        public LMOtsPublicKey GetPublicKey()
-        {
-            return publicKey;
-        }
+        public LMOtsPublicKey PublicKey => m_publicKey;
 
-        internal LMSigParameters GetSigParams()
-        {
-            return sigParams;
-        }
+        internal LMSigParameters SigParams => m_sigParams;
 
-        public Object GetSignature()
-        {
-            return signature;
-        }
+        public object Signature => m_signature;
 
-        internal LMSSignedPubKey[] GetSignedPubKeys()
-        {
-            return signedPubKeys;
-        }
+        internal LMSSignedPubKey[] SignedPubKeys => m_signedPubKeys;
 
         internal LMSContext WithSignedPublicKeys(LMSSignedPubKey[] signedPubKeys)
         {
-            this.signedPubKeys = signedPubKeys;
-
+            m_signedPubKeys = signedPubKeys;
             return this;
         }
 
-        public string AlgorithmName
-        {
-            get => digest.AlgorithmName;
-        }
+        public string AlgorithmName => m_digest.AlgorithmName;
 
-        public int GetDigestSize()
-        {
-            return digest.GetDigestSize();
-        }
+        public int GetDigestSize() => m_digest.GetDigestSize();
 
-        public int GetByteLength()
-        {
-            return digest.GetByteLength();
-        }
+        public int GetByteLength() => m_digest.GetByteLength();
 
         public void Update(byte input)
         {
-            digest.Update(input);
+            m_digest.Update(input);
         }
 
         public void BlockUpdate(byte[] input, int inOff, int len)
         {
-            digest.BlockUpdate(input, inOff, len);
+            m_digest.BlockUpdate(input, inOff, len);
         }
 
         public int DoFinal(byte[] output, int outOff)
         {
-            return digest.DoFinal(output, outOff);
+            return m_digest.DoFinal(output, outOff);
         }
 
         public void Reset()
         {
-            digest.Reset();
+            m_digest.Reset();
         }
 
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
         public void BlockUpdate(ReadOnlySpan<byte> input)
         {
-            digest.BlockUpdate(input);
+            m_digest.BlockUpdate(input);
         }
 
         public int DoFinal(Span<byte> output)
         {
-            return digest.DoFinal(output);
+            return m_digest.DoFinal(output);
         }
 #endif
     }
diff --git a/crypto/src/pqc/crypto/lms/LMSKeyGenerationParameters.cs b/crypto/src/pqc/crypto/lms/LMSKeyGenerationParameters.cs
index 837b8783a..dd932c17d 100644
--- a/crypto/src/pqc/crypto/lms/LMSKeyGenerationParameters.cs
+++ b/crypto/src/pqc/crypto/lms/LMSKeyGenerationParameters.cs
@@ -3,11 +3,10 @@ using Org.BouncyCastle.Security;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-
     public class LMSKeyGenerationParameters
         : KeyGenerationParameters
     {
-        private LMSParameters lmsParameters;
+        private readonly LMSParameters m_lmsParameters;
 
         /**
          * Base constructor - parameters and a source of randomness.
@@ -18,13 +17,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         public LMSKeyGenerationParameters(LMSParameters lmsParameters, SecureRandom random)
             : base(random, LmsUtils.CalculateStrength(lmsParameters)) // TODO: need something for "strength"
         {
-            this.lmsParameters = lmsParameters;
+            m_lmsParameters = lmsParameters;
         }
 
-        public LMSParameters GetParameters()
-        {
-            return lmsParameters;
-        }
+        public LMSParameters LmsParameters => m_lmsParameters;
     }
 }
-
diff --git a/crypto/src/pqc/crypto/lms/LMSKeyPairGenerator.cs b/crypto/src/pqc/crypto/lms/LMSKeyPairGenerator.cs
index 3213c8ab1..9147c3fdf 100644
--- a/crypto/src/pqc/crypto/lms/LMSKeyPairGenerator.cs
+++ b/crypto/src/pqc/crypto/lms/LMSKeyPairGenerator.cs
@@ -3,19 +3,19 @@ using Org.BouncyCastle.Security;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-    public class LMSKeyPairGenerator
+    public sealed class LMSKeyPairGenerator
         : IAsymmetricCipherKeyPairGenerator
     {
-        private LMSKeyGenerationParameters param;
+        private LMSKeyGenerationParameters m_parameters;
 
-        public void Init(KeyGenerationParameters param)
+        public void Init(KeyGenerationParameters parameters)
         {
-            this.param = (LMSKeyGenerationParameters) param;
+            m_parameters = (LMSKeyGenerationParameters)parameters;
         }
 
         public AsymmetricCipherKeyPair GenerateKeyPair()
         {
-            SecureRandom source = param.Random;
+            SecureRandom source = m_parameters.Random;
 
             byte[] I = new byte[16];
             source.NextBytes(I);
@@ -23,11 +23,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             byte[] rootSecret = new byte[32];
             source.NextBytes(rootSecret);
 
-            LMSPrivateKeyParameters privKey = LMS.GenerateKeys(param.GetParameters().GetLmSigParam(),
-                param.GetParameters().GetLmotsParam(), 0, I, rootSecret);
+            LMSPrivateKeyParameters privKey = LMS.GenerateKeys(m_parameters.LmsParameters.LMSigParameters,
+                m_parameters.LmsParameters.LMOtsParameters, 0, I, rootSecret);
 
             return new AsymmetricCipherKeyPair(privKey.GetPublicKey(), privKey);
         }
     }
-    
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/LMSKeyParameters.cs b/crypto/src/pqc/crypto/lms/LMSKeyParameters.cs
index 07123be7c..e4b2df66d 100644
--- a/crypto/src/pqc/crypto/lms/LMSKeyParameters.cs
+++ b/crypto/src/pqc/crypto/lms/LMSKeyParameters.cs
@@ -1,6 +1,3 @@
-
-
-using System;
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Utilities;
 
@@ -10,9 +7,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         : AsymmetricKeyParameter, IEncodable
     {
         protected LMSKeyParameters(bool isPrivateKey)
-            : base(isPrivateKey) { }
+            : base(isPrivateKey)
+        {
+        }
 
         public abstract byte[] GetEncoded();
     }
-    
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/LMSParameters.cs b/crypto/src/pqc/crypto/lms/LMSParameters.cs
index 0f68b968f..adffad2da 100644
--- a/crypto/src/pqc/crypto/lms/LMSParameters.cs
+++ b/crypto/src/pqc/crypto/lms/LMSParameters.cs
@@ -1,24 +1,18 @@
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-    public class LMSParameters
+    public sealed class LMSParameters
     {
-        private LMSigParameters lmSigParam;
-        private LMOtsParameters lmOTSParam;
+        private readonly LMSigParameters m_lmSigParameters;
+        private readonly LMOtsParameters m_lmOtsParameters;
 
-        public LMSParameters(LMSigParameters lmSigParam, LMOtsParameters lmOTSParam)
+        public LMSParameters(LMSigParameters lmSigParameters, LMOtsParameters lmOtsParameters)
         {
-            this.lmSigParam = lmSigParam;
-            this.lmOTSParam = lmOTSParam;
+            m_lmSigParameters = lmSigParameters;
+            m_lmOtsParameters = lmOtsParameters;
         }
 
-        public LMSigParameters GetLmSigParam()
-        {
-            return lmSigParam;
-        }
+        public LMSigParameters LMSigParameters => m_lmSigParameters;
 
-        public LMOtsParameters GetLmotsParam()
-        {
-            return lmOTSParam;
-        }
+        public LMOtsParameters LMOtsParameters => m_lmOtsParameters;
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/LMSPrivateKeyParameters.cs b/crypto/src/pqc/crypto/lms/LMSPrivateKeyParameters.cs
index fe3f9899d..f83cdc5f4 100644
--- a/crypto/src/pqc/crypto/lms/LMSPrivateKeyParameters.cs
+++ b/crypto/src/pqc/crypto/lms/LMSPrivateKeyParameters.cs
@@ -1,14 +1,12 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
+
 using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Pqc.Crypto.Lms;
 using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.IO;
 
-using static Org.BouncyCastle.Pqc.Crypto.Lms.LMS;
-
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
     public class LMSPrivateKeyParameters
@@ -53,9 +51,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             this.I = Arrays.Clone(I);
             this.maxQ = maxQ;
             this.masterSecret = Arrays.Clone(masterSecret);
-            this.maxCacheR = 1 << (parameters.GetH() + 1);
+            this.maxCacheR = 1 << (parameters.H + 1);
             this.tCache = new Dictionary<CacheKey, byte[]>();
-            this.tDigest = DigestUtilities.GetDigest(lmsParameter.GetDigestOid());
+            this.tDigest = DigestUtilities.GetDigest(lmsParameter.DigestOid);
         }
 
         private LMSPrivateKeyParameters(LMSPrivateKeyParameters parent, int q, int maxQ)
@@ -67,9 +65,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             this.I = parent.I;
             this.maxQ = maxQ;
             this.masterSecret = parent.masterSecret;
-            this.maxCacheR = 1 << parameters.GetH();
+            this.maxCacheR = 1 << parameters.H;
             this.tCache = parent.tCache;
-            this.tDigest = DigestUtilities.GetDigest(parameters.GetDigestOid());
+            this.tDigest = DigestUtilities.GetDigest(parameters.DigestOid);
             this.publicKey = parent.publicKey;
         }
 
@@ -115,13 +113,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                 byte[] data = ((BinaryReader) src).ReadBytes(4);
                 Array.Reverse(data);
                 int paramType = BitConverter.ToInt32(data, 0);
-                LMSigParameters parameter = LMSigParameters.GetParametersForType(paramType);
-                
+                LMSigParameters parameter = LMSigParameters.GetParametersByID(paramType);
+
                 data = ((BinaryReader) src).ReadBytes(4);
                 Array.Reverse(data);
                 paramType = BitConverter.ToInt32(data, 0);
                 
-                LMOtsParameters otsParameter = LMOtsParameters.GetParametersForType(paramType);
+                LMOtsParameters otsParameter = LMOtsParameters.GetParametersByID(paramType);
                 byte[] I = new byte[16];
                 dIn.Read(I, 0, I.Length);
             
@@ -213,7 +211,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             LMSigParameters lmsParameter = this.GetSigParameters();
 
             // Step 2
-            int h = lmsParameter.GetH();
+            int h = lmsParameter.H;
             int q = GetIndex();
             LMOtsPrivateKey otsPk = GetNextOtsPrivateKey();
 
@@ -236,7 +234,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         {
             try
             {
-                return GenerateSign(context).GetEncoded();
+                return LMS.GenerateSign(context).GetEncoded();
             }
             catch (IOException e)
             {
@@ -244,7 +242,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             }
         }
 
-        LMOtsPrivateKey GetNextOtsPrivateKey()
+        internal virtual LMOtsPrivateKey GetNextOtsPrivateKey()
         {
             lock (this)
             {
@@ -258,7 +256,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             }
         }
 
-
         /**
          * Return a key that can be used usageCount times.
          * <p>
@@ -308,7 +305,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             return maxQ - q;
         }
 
-        public LMSPublicKeyParameters GetPublicKey()
+        public virtual LMSPublicKeyParameters GetPublicKey()
         {
             lock (this)
             {
@@ -347,7 +344,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
         private byte[] CalcT(int r)
         {
-            int h = this.GetSigParameters().GetH();
+            int h = this.GetSigParameters().H;
 
             int twoToh = 1 << h;
 
@@ -359,12 +356,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             {
                 LmsUtils.ByteArray(this.GetI(), tDigest);
                 LmsUtils.U32Str(r, tDigest);
-                LmsUtils.U16Str(D_LEAF, tDigest);
+                LmsUtils.U16Str(LMS.D_LEAF, tDigest);
                 //
                 // These can be pre generated at the time of key generation and held within the private key.
                 // However it will cost memory to have them stick around.
                 //
-                byte[] K = LM_OTS.lms_ots_generatePublicKey(this.GetOtsParameters(), this.GetI(), (r - twoToh), this.GetMasterSecret());
+                byte[] K = LM_OTS.LmsOtsGeneratePublicKey(this.GetOtsParameters(), this.GetI(), (r - twoToh),
+                    this.GetMasterSecret());
 
                 LmsUtils.ByteArray(K, tDigest);
                 T = new byte[tDigest.GetDigestSize()];
@@ -377,7 +375,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
             LmsUtils.ByteArray(this.GetI(), tDigest);
             LmsUtils.U32Str(r, tDigest);
-            LmsUtils.U16Str(D_INTR, tDigest);
+            LmsUtils.U16Str(LMS.D_INTR, tDigest);
             LmsUtils.ByteArray(t2r, tDigest);
             LmsUtils.ByteArray(t2rPlus1, tDigest);
             T = new byte[tDigest.GetDigestSize()];
@@ -467,8 +465,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
             return Composer.Compose()
                 .U32Str(0) // version
-                .U32Str(parameters.GetType()) // type
-                .U32Str(otsParameters.GetType()) // ots type
+                .U32Str(parameters.ID) // type
+                .U32Str(otsParameters.ID) // ots type
                 .Bytes(I) // I at 16 bytes
                 .U32Str(q) // q
                 .U32Str(maxQ) // maximum q
diff --git a/crypto/src/pqc/crypto/lms/LMSPublicKeyParameters.cs b/crypto/src/pqc/crypto/lms/LMSPublicKeyParameters.cs
index d58d3d924..1bf857f60 100644
--- a/crypto/src/pqc/crypto/lms/LMSPublicKeyParameters.cs
+++ b/crypto/src/pqc/crypto/lms/LMSPublicKeyParameters.cs
@@ -1,11 +1,9 @@
 using System;
 using System.IO;
-using Org.BouncyCastle.Pqc.Crypto.Lms;
+
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.IO;
 
-using static Org.BouncyCastle.Pqc.Crypto.Lms.LMS;
-
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
     public class LMSPublicKeyParameters
@@ -27,37 +25,36 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
         public static LMSPublicKeyParameters GetInstance(Object src)
         {
-            if (src is LMSPublicKeyParameters)
+            if (src is LMSPublicKeyParameters lmsPublicKeyParameters)
             {
-                return (LMSPublicKeyParameters)src;
+                return lmsPublicKeyParameters;
             }
             // todo
-             else if (src is BinaryReader)
+             else if (src is BinaryReader binaryReader)
              {
-                 byte[] data = ((BinaryReader) src).ReadBytes(4);
+                 byte[] data = binaryReader.ReadBytes(4);
                  Array.Reverse(data);
                  int pubType = BitConverter.ToInt32(data, 0);
-                 LMSigParameters lmsParameter = LMSigParameters.GetParametersForType(pubType);
+                 LMSigParameters lmsParameter = LMSigParameters.GetParametersByID(pubType);
                  
-                 data = ((BinaryReader) src).ReadBytes(4);
+                 data = binaryReader.ReadBytes(4);
                  Array.Reverse(data);
                  int index = BitConverter.ToInt32(data, 0);
-                 LMOtsParameters ostTypeCode = LMOtsParameters.GetParametersForType(index);
+                 LMOtsParameters ostTypeCode = LMOtsParameters.GetParametersByID(index);
             
                  byte[] I = new byte[16];
-                 ((BinaryReader)src).Read(I, 0, I.Length);//change to readbytes?
+                binaryReader.Read(I, 0, I.Length);//change to readbytes?
             
-                 byte[] T1 = new byte[lmsParameter.GetM()];
-                 ((BinaryReader)src).Read(T1, 0, T1.Length);
+                 byte[] T1 = new byte[lmsParameter.M];
+                binaryReader.Read(T1, 0, T1.Length);
                  return new LMSPublicKeyParameters(lmsParameter, ostTypeCode, T1, I);
              }
-             else if (src is byte[])
+             else if (src is byte[] bytes)
              {
-            
                  BinaryReader input = null;
                  try // 1.5 / 1.6 compatibility
                  {
-                     input = new BinaryReader(new MemoryStream((byte[])src, false));
+                     input = new BinaryReader(new MemoryStream(bytes, false));
                      return GetInstance(input);
                  }
                  finally
@@ -68,9 +65,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                      }
                  }
              }
-            else if (src is MemoryStream)
+            else if (src is MemoryStream memoryStream)
             {
-                return GetInstance(Streams.ReadAll((Stream)src));
+                return GetInstance(Streams.ReadAll(memoryStream));
             }
             throw new Exception ($"cannot parse {src}");
         }
@@ -155,8 +152,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         internal byte[] ToByteArray()
         {
             return Composer.Compose()
-                .U32Str(parameterSet.GetType())
-                .U32Str(lmOtsType.GetType())
+                .U32Str(parameterSet.ID)
+                .U32Str(lmOtsType.ID)
                 .Bytes(I)
                 .Bytes(T1)
                 .Build();
@@ -176,19 +173,20 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
         internal LMSContext GenerateOtsContext(LMSSignature S)
         {
-            int ots_typecode = GetOtsParameters().GetType();
-            if (S.GetOtsSignature().GetParamType().GetType() != ots_typecode)
+            int ots_typecode = GetOtsParameters().ID;
+            if (S.OtsSignature.ParamType.ID != ots_typecode)
             {
                 throw new ArgumentException("ots type from lsm signature does not match ots" +
                     " signature type from embedded ots signature");
             }
 
-            return new LMOtsPublicKey(LMOtsParameters.GetParametersForType(ots_typecode), I,  S.GetQ(), null).CreateOtsContext(S);
+            return new LMOtsPublicKey(LMOtsParameters.GetParametersByID(ots_typecode), I,  S.Q, null)
+                .CreateOtsContext(S);
         }
 
         public bool Verify(LMSContext context)
         {
-            return VerifySignature(this, context);
+            return LMS.VerifySignature(this, context);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/LMSSignature.cs b/crypto/src/pqc/crypto/lms/LMSSignature.cs
index 8769160b4..48026e2f6 100644
--- a/crypto/src/pqc/crypto/lms/LMSSignature.cs
+++ b/crypto/src/pqc/crypto/lms/LMSSignature.cs
@@ -22,40 +22,40 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             this.y = y;
         }
 
-        public static LMSSignature GetInstance(Object src)
+        public static LMSSignature GetInstance(object src)
         {
-            if (src is LMSSignature)
+            if (src is LMSSignature lmsSignature)
             {
-                return (LMSSignature)src;
+                return lmsSignature;
             }
-            else if (src is BinaryReader)
+            else if (src is BinaryReader binaryReader)
             {
-                byte[] data = ((BinaryReader)src).ReadBytes(4);
+                byte[] data = binaryReader.ReadBytes(4);
                 Array.Reverse(data);
                 int q = BitConverter.ToInt32(data, 0);
                 
                 LMOtsSignature otsSignature = LMOtsSignature.GetInstance(src);
 
-                data = ((BinaryReader) src).ReadBytes(4);
+                data = binaryReader.ReadBytes(4);
                 Array.Reverse(data);
                 int index = BitConverter.ToInt32(data, 0);
-                LMSigParameters type = LMSigParameters.GetParametersForType(index);
-            
-                byte[][] path = new byte[type.GetH()][];
+                LMSigParameters type = LMSigParameters.GetParametersByID(index);
+
+                byte[][] path = new byte[type.H][];
                 for (int h = 0; h < path.Length; h++)
                 {
-                    path[h] = new byte[type.GetM()];
-                    ((BinaryReader)src).Read(path[h], 0, path[h].Length);
+                    path[h] = new byte[type.M];
+                    binaryReader.Read(path[h], 0, path[h].Length);
                 }
             
                 return new LMSSignature(q, otsSignature, type, path);
             }
-            else if (src is byte[])
+            else if (src is byte[] bytes)
             {
                 BinaryReader input = null;
                 try // 1.5 / 1.6 compatibility
                 {
-                    input = new BinaryReader(new MemoryStream( (byte[]) src, false));
+                    input = new BinaryReader(new MemoryStream(bytes, false));
                     return GetInstance(input);
                 }
                 finally
@@ -63,9 +63,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                     if (input != null) input.Close();// todo platform dispose
                 }
             }
-            else if (src is MemoryStream)
+            else if (src is MemoryStream memoryStream)
             {
-                return GetInstance(Streams.ReadAll((Stream)src));
+                return GetInstance(Streams.ReadAll(memoryStream));
             }
             throw new Exception ($"cannot parse {src}");
         }
@@ -126,29 +126,18 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             return Composer.Compose()
                 .U32Str(q)
                 .Bytes(otsSignature.GetEncoded())
-                .U32Str(parameter.GetType())
+                .U32Str(parameter.ID)
                 .Bytes(y)
                 .Build();
         }
 
-        public int GetQ()
-        {
-            return q;
-        }
+        public int Q => q;
 
-        public LMOtsSignature GetOtsSignature()
-        {
-            return otsSignature;
-        }
+        public LMOtsSignature OtsSignature => otsSignature;
 
-        public LMSigParameters GetParameter()
-        {
-            return parameter;
-        }
+        public LMSigParameters SigParameters => parameter;
 
-        public byte[][] GetY()
-        {
-            return y;
-        }
+        // FIXME
+        public byte[][] Y => y;
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/LMSSignedPubKey.cs b/crypto/src/pqc/crypto/lms/LMSSignedPubKey.cs
index 20d1bade5..024ee5f4c 100644
--- a/crypto/src/pqc/crypto/lms/LMSSignedPubKey.cs
+++ b/crypto/src/pqc/crypto/lms/LMSSignedPubKey.cs
@@ -1,4 +1,5 @@
 using System;
+
 using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
diff --git a/crypto/src/pqc/crypto/lms/LMSSigner.cs b/crypto/src/pqc/crypto/lms/LMSSigner.cs
index a5aebd312..05824307a 100644
--- a/crypto/src/pqc/crypto/lms/LMSSigner.cs
+++ b/crypto/src/pqc/crypto/lms/LMSSigner.cs
@@ -5,21 +5,21 @@ using Org.BouncyCastle.Crypto;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-    public class LMSSigner
+    public sealed class LMSSigner
         : IMessageSigner
     {
-        private LMSPrivateKeyParameters privKey;
-        private LMSPublicKeyParameters pubKey;
+        private LMSPrivateKeyParameters m_privateKey;
+        private LMSPublicKeyParameters m_publicKey;
 
         public void Init(bool forSigning, ICipherParameters param)
         {
             if (forSigning)
             {
-                privKey = (LMSPrivateKeyParameters)param;
+                m_privateKey = (LMSPrivateKeyParameters)param;
             }
             else
             {
-                pubKey = (LMSPublicKeyParameters)param;
+                m_publicKey = (LMSPublicKeyParameters)param;
             }
         }
 
@@ -27,7 +27,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         {
             try
             {
-                return LMS.GenerateSign(privKey, message).GetEncoded();
+                return LMS.GenerateSign(m_privateKey, message).GetEncoded();
             }
             catch (IOException e)
             {
@@ -39,7 +39,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         {
             try
             {
-                return LMS.VerifySignature(pubKey, LMSSignature.GetInstance(signature), message);
+                return LMS.VerifySignature(m_publicKey, LMSSignature.GetInstance(signature), message);
             }
             catch (IOException e)
             {
@@ -47,4 +47,4 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/LMSigParameters.cs b/crypto/src/pqc/crypto/lms/LMSigParameters.cs
index 7b4053e69..79a9d2ad5 100644
--- a/crypto/src/pqc/crypto/lms/LMSigParameters.cs
+++ b/crypto/src/pqc/crypto/lms/LMSigParameters.cs
@@ -1,11 +1,13 @@
-using System;
 using System.Collections.Generic;
+
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-    public class LMSigParameters
+    public sealed class LMSigParameters
     {
         public static LMSigParameters lms_sha256_n32_h5 = new LMSigParameters(5, 32, 5, NistObjectIdentifiers.IdSha256);
         public static LMSigParameters lms_sha256_n32_h10 = new LMSigParameters(6, 32, 10, NistObjectIdentifiers.IdSha256);
@@ -13,52 +15,39 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         public static LMSigParameters lms_sha256_n32_h20 = new LMSigParameters(8, 32, 20, NistObjectIdentifiers.IdSha256);
         public static LMSigParameters lms_sha256_n32_h25 = new LMSigParameters(9, 32, 25, NistObjectIdentifiers.IdSha256);
 
-
-        private static Dictionary<int, LMSigParameters> paramBuilders = new Dictionary<int, LMSigParameters>
+        private static Dictionary<int, LMSigParameters> ParametersByID = new Dictionary<int, LMSigParameters>
         {
-            { lms_sha256_n32_h5.type,  lms_sha256_n32_h5  },
-            { lms_sha256_n32_h10.type, lms_sha256_n32_h10 },
-            { lms_sha256_n32_h15.type, lms_sha256_n32_h15 },
-            { lms_sha256_n32_h20.type, lms_sha256_n32_h20 },
-            { lms_sha256_n32_h25.type, lms_sha256_n32_h25 }
+            { lms_sha256_n32_h5.ID, lms_sha256_n32_h5 },
+            { lms_sha256_n32_h10.ID, lms_sha256_n32_h10 },
+            { lms_sha256_n32_h15.ID, lms_sha256_n32_h15 },
+            { lms_sha256_n32_h20.ID, lms_sha256_n32_h20 },
+            { lms_sha256_n32_h25.ID, lms_sha256_n32_h25 }
         };
 
-        private int type;
-        private int m;
-        private int h;
-        private DerObjectIdentifier digestOid;
-
-        protected LMSigParameters(int type, int m, int h, DerObjectIdentifier digestOid)
-        {
-            this.type = type;
-            this.m = m;
-            this.h = h;
-            this.digestOid = digestOid;
+        private readonly int m_id;
+        private readonly int m_m;
+        private readonly int m_h;
+        private readonly DerObjectIdentifier m_digestOid;
 
-        }
-        public int GetType()
+        protected LMSigParameters(int id, int m, int h, DerObjectIdentifier digestOid)
         {
-            return type;
+            m_id = id;
+            m_m = m;
+            m_h = h;
+            m_digestOid = digestOid;
         }
 
-        public int GetH()
-        {
-            return h;
-        }
+        public int ID => m_id;
 
-        public int GetM()
-        {
-            return m;
-        }
+        public int H => m_h;
 
-        public DerObjectIdentifier GetDigestOid()
-        {
-            return digestOid;
-        }
+        public int M => m_m;
+
+        public DerObjectIdentifier DigestOid => m_digestOid;
 
-        public static LMSigParameters GetParametersForType(int type)
+        public static LMSigParameters GetParametersByID(int id)
         {
-            return paramBuilders[type];
+            return CollectionUtilities.GetValueOrNull(ParametersByID, id);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/LM_OTS.cs b/crypto/src/pqc/crypto/lms/LM_OTS.cs
index d5662bd9a..b9634c652 100644
--- a/crypto/src/pqc/crypto/lms/LM_OTS.cs
+++ b/crypto/src/pqc/crypto/lms/LM_OTS.cs
@@ -1,4 +1,5 @@
 using System;
+
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.Utilities;
 using Org.BouncyCastle.Security;
@@ -18,7 +19,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         internal static int MAX_HASH = 32;
         internal static ushort D_MESG = 0x8181;
 
-
         public static int Coef(byte[] S, int i, int w)
         {
             int index = (i * w) / 8;
@@ -29,38 +29,35 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             return (S[index] >> shift) & mask;
         }
 
-
         public static int Cksm(byte[] S, int sLen, LMOtsParameters parameters)
         {
             int sum = 0;
 
-            int w = parameters.GetW();
+            int w = parameters.W;
 
             // NB assumption about size of "w" not overflowing integer.
             int twoWpow = (1 << w) - 1;
 
-            for (int i = 0; i < (sLen * 8 / parameters.GetW()); i++)
+            for (int i = 0; i < (sLen * 8 / parameters.W); i++)
             {
-                sum = sum + twoWpow - Coef(S, i, parameters.GetW());
+                sum = sum + twoWpow - Coef(S, i, parameters.W);
             }
-            return sum << parameters.GetLs();
+            return sum << parameters.Ls;
         }
 
-
-        public static LMOtsPublicKey lms_ots_generatePublicKey(LMOtsPrivateKey privateKey)
+        public static LMOtsPublicKey LmsOtsGeneratePublicKey(LMOtsPrivateKey privateKey)
         {
-            byte[] K = lms_ots_generatePublicKey(privateKey.GetParameter(), privateKey.GetI(), privateKey.GetQ(), privateKey.GetMasterSecret());
-            return new LMOtsPublicKey(privateKey.GetParameter(), privateKey.GetI(), privateKey.GetQ(), K);
+            byte[] K = LmsOtsGeneratePublicKey(privateKey.Parameters, privateKey.I, privateKey.Q,
+                privateKey.MasterSecret);
+            return new LMOtsPublicKey(privateKey.Parameters, privateKey.I, privateKey.Q, K);
         }
 
-        internal static byte[] lms_ots_generatePublicKey(LMOtsParameters parameter, byte[] I, int q, byte[] masterSecret)
+        internal static byte[] LmsOtsGeneratePublicKey(LMOtsParameters parameter, byte[] I, int q, byte[] masterSecret)
         {
-
-
             //
             // Start hash that computes the final value.
             //
-            IDigest publicContext = DigestUtilities.GetDigest(parameter.GetDigestOid());
+            IDigest publicContext = DigestUtilities.GetDigest(parameter.DigestOid);
             byte[] prehashPrefix = Composer.Compose()
                 .Bytes(I)
                 .U32Str(q)
@@ -69,7 +66,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                 .Build();
             publicContext.BlockUpdate(prehashPrefix, 0, prehashPrefix.Length);
 
-            IDigest ctx = DigestUtilities.GetDigest(parameter.GetDigestOid());
+            IDigest ctx = DigestUtilities.GetDigest(parameter.DigestOid);
 
             byte[] buf = Composer.Compose()
                 .Bytes(I)
@@ -77,19 +74,19 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                 .PadUntil(0, 23 + ctx.GetDigestSize())
                 .Build();
 
+            SeedDerive derive = new SeedDerive(I, masterSecret, DigestUtilities.GetDigest(parameter.DigestOid))
+            {
+                Q = q,
+                J = 0,
+            };
 
-            SeedDerive derive = new SeedDerive(I, masterSecret, DigestUtilities.GetDigest(parameter.GetDigestOid()));
-            derive.SetQ(q);
-            derive.SetJ(0);
-
-            int p = parameter.GetP();
-            int n = parameter.GetN();
-            int twoToWminus1 = (1 << parameter.GetW()) - 1;
-
+            int p = parameter.P;
+            int n = parameter.N;
+            int twoToWminus1 = (1 << parameter.W) - 1;
 
             for (ushort i = 0; i < p; i++)
             {
-                derive.deriveSeed(buf, i < p - 1, ITER_PREV); // Private Key!
+                derive.DeriveSeed(i < p - 1, buf, ITER_PREV); // Private Key!
                 Pack.UInt16_To_BE(i, buf, ITER_K);
                 for (int j = 0; j < twoToWminus1; j++)
                 {
@@ -102,17 +99,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
             byte[] K = new byte[publicContext.GetDigestSize()];
             publicContext.DoFinal(K, 0);
-
             return K;
-
         }
 
-        public static LMOtsSignature lm_ots_generate_signature(LMSigParameters sigParams, LMOtsPrivateKey privateKey, byte[][] path, byte[] message, bool preHashed)
+        public static LMOtsSignature lm_ots_generate_signature(LMSigParameters sigParams, LMOtsPrivateKey privateKey,
+            byte[][] path, byte[] message, bool preHashed)
         {
             //
             // Add the randomizer.
             //
-
             byte[] C;
             byte[] Q = new byte[MAX_HASH + 2];
 
@@ -128,23 +123,23 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             else
             {
                 C = new byte[SEED_LEN];
-                Array.Copy(message, 0, Q, 0, privateKey.GetParameter().GetN());
+                Array.Copy(message, 0, Q, 0, privateKey.Parameters.N);
             }
 
-            return lm_ots_generate_signature(privateKey, Q, C);
+            return LMOtsGenerateSignature(privateKey, Q, C);
         }
 
-        public static LMOtsSignature lm_ots_generate_signature(LMOtsPrivateKey privateKey, byte[] Q, byte[] C)
+        public static LMOtsSignature LMOtsGenerateSignature(LMOtsPrivateKey privateKey, byte[] Q, byte[] C)
         {
-            LMOtsParameters parameter = privateKey.GetParameter();
+            LMOtsParameters parameter = privateKey.Parameters;
 
-            int n = parameter.GetN();
-            int p = parameter.GetP();
-            int w = parameter.GetW();
+            int n = parameter.N;
+            int p = parameter.P;
+            int w = parameter.W;
 
             byte[] sigComposer = new byte[p * n];
 
-            IDigest ctx = DigestUtilities.GetDigest(parameter.GetDigestOid());
+            IDigest ctx = DigestUtilities.GetDigest(parameter.DigestOid);
 
             SeedDerive derive = privateKey.GetDerivationFunction();
 
@@ -153,16 +148,16 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             Q[n + 1] = (byte)cs;
 
             byte[] tmp = Composer.Compose()
-                .Bytes(privateKey.GetI())
-                .U32Str(privateKey.GetQ())
+                .Bytes(privateKey.I)
+                .U32Str(privateKey.Q)
                 .PadUntil(0, ITER_PREV + n)
                 .Build();
 
-            derive.SetJ(0);
+            derive.J = 0;
             for (ushort i = 0; i < p; i++)
             {
                 Pack.UInt16_To_BE(i, tmp, ITER_K);
-                derive.deriveSeed(tmp, i < p - 1, ITER_PREV);
+                derive.DeriveSeed(i < p - 1, tmp, ITER_PREV);
                 int a = Coef(Q, i, w);
                 for (int j = 0; j < a; j++)
                 {
@@ -176,52 +171,53 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             return new LMOtsSignature(parameter, C, sigComposer);
         }
 
-        public static bool lm_ots_validate_signature(LMOtsPublicKey publicKey, LMOtsSignature signature, byte[] message, bool prehashed)
+        public static bool LMOtsValidateSignature(LMOtsPublicKey publicKey, LMOtsSignature signature, byte[] message,
+            bool prehashed)
         {
-            if (!signature.GetParamType().Equals(publicKey.GetParameter())) // todo check
-            {
+            if (!signature.ParamType.Equals(publicKey.Parameters)) // todo check
                 throw new LMSException("public key and signature ots types do not match");
-            }
-            return Arrays.AreEqual(lm_ots_validate_signature_calculate(publicKey, signature, message), publicKey.GetK());
+
+            return Arrays.AreEqual(LMOtsValidateSignatureCalculate(publicKey, signature, message), publicKey.K);
         }
 
-        public static byte[] lm_ots_validate_signature_calculate(LMOtsPublicKey publicKey, LMOtsSignature signature, byte[] message)
+        public static byte[] LMOtsValidateSignatureCalculate(LMOtsPublicKey publicKey, LMOtsSignature signature, 
+            byte[] message)
         {
             LMSContext ctx = publicKey.CreateOtsContext(signature);
 
             LmsUtils.ByteArray(message, ctx);
 
-            return lm_ots_validate_signature_calculate(ctx);
+            return LMOtsValidateSignatureCalculate(ctx);
         }
 
-        public static byte[] lm_ots_validate_signature_calculate(LMSContext context)
+        public static byte[] LMOtsValidateSignatureCalculate(LMSContext context)
         {
-            LMOtsPublicKey publicKey = context.GetPublicKey();
-            LMOtsParameters parameter = publicKey.GetParameter();
-            Object sig = context.GetSignature();
+            LMOtsPublicKey publicKey = context.PublicKey;
+            LMOtsParameters parameter = publicKey.Parameters;
+            object sig = context.Signature;
             LMOtsSignature signature;
             if (sig is LMSSignature)
             {
-                signature = ((LMSSignature)sig).GetOtsSignature();
+                signature = ((LMSSignature)sig).OtsSignature;
             }
             else
             {
                 signature = (LMOtsSignature)sig;
             }
 
-            int n = parameter.GetN();
-            int w = parameter.GetW();
-            int p = parameter.GetP();
+            int n = parameter.N;
+            int w = parameter.W;
+            int p = parameter.P;
             byte[] Q = context.GetQ();
 
             int cs = Cksm(Q, n, parameter);
             Q[n] = (byte)((cs >> 8) & 0xFF);
             Q[n + 1] = (byte)cs;
 
-            byte[] I = publicKey.GetI();
-            int    q = publicKey.GetQ();
+            byte[] I = publicKey.I;
+            int q = publicKey.Q;
 
-            IDigest finalContext = DigestUtilities.GetDigest(parameter.GetDigestOid());
+            IDigest finalContext = DigestUtilities.GetDigest(parameter.DigestOid);
             LmsUtils.ByteArray(I, finalContext);
             LmsUtils.U32Str(q, finalContext);
             LmsUtils.U16Str(D_PBLC, finalContext);
@@ -234,9 +230,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
             int max_digit = (1 << w) - 1;
 
-            byte[] y = signature.GetY();
+            byte[] y = signature.Y;
 
-            IDigest ctx = DigestUtilities.GetDigest(parameter.GetDigestOid());
+            IDigest ctx = DigestUtilities.GetDigest(parameter.DigestOid);
             for (ushort i = 0; i < p; i++)
             {
                 Pack.UInt16_To_BE(i, tmp, ITER_K);
@@ -259,4 +255,4 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             return K;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/LmsUtils.cs b/crypto/src/pqc/crypto/lms/LmsUtils.cs
index 04696f830..3b08b009d 100644
--- a/crypto/src/pqc/crypto/lms/LmsUtils.cs
+++ b/crypto/src/pqc/crypto/lms/LmsUtils.cs
@@ -1,4 +1,5 @@
 using System;
+
 using Org.BouncyCastle.Crypto;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
@@ -32,12 +33,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         public static int CalculateStrength(LMSParameters lmsParameters)
         {
             if (lmsParameters == null)
-            {
-                throw new NullReferenceException("lmsParameters cannot be null");
-            }
+                throw new ArgumentNullException(nameof(lmsParameters));
 
-            LMSigParameters sigParameters = lmsParameters.GetLmSigParam();
-            return (1 << sigParameters.GetH()) * sigParameters.GetM();
+            LMSigParameters sigParameters = lmsParameters.LMSigParameters;
+            return sigParameters.M << sigParameters.H;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/lms/SeedDerive.cs b/crypto/src/pqc/crypto/lms/SeedDerive.cs
index 58083a329..38b72fd3f 100644
--- a/crypto/src/pqc/crypto/lms/SeedDerive.cs
+++ b/crypto/src/pqc/crypto/lms/SeedDerive.cs
@@ -1,94 +1,69 @@
 using System;
+
 using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Utilities;
 
 namespace Org.BouncyCastle.Pqc.Crypto.Lms
 {
-    public class SeedDerive
+    public sealed class SeedDerive
     {
-        private byte[] I;
-        private byte[] masterSeed;
-        private IDigest digest;
-        private int q;
-        private int j;
-
+        private readonly byte[] m_I;
+        private readonly byte[] m_masterSeed;
+        private readonly IDigest m_digest;
 
         public SeedDerive(byte[] I, byte[] masterSeed, IDigest digest)
         {
-            this.I = I;
-            this.masterSeed = masterSeed;
-            this.digest = digest;
+            m_I = I;
+            m_masterSeed = masterSeed;
+            m_digest = digest;
         }
 
-        public int GetQ()
-        {
-            return q;
-        }
+        public int Q { get; set; }
 
-        public void SetQ(int q)
-        {
-            this.q = q;
-        }
+        public int J { get; set; }
 
-        public int GetJ()
-        {
-            return j;
-        }
+        // FIXME
+        public byte[] I => m_I;
 
-        public void SetJ(int j)
-        {
-            this.j = j;
-        }
+        // FIXME
+        public byte[] MasterSeed => m_masterSeed;
 
-        public byte[] GetI()
+        public byte[] DeriveSeed(bool incJ, byte[] target, int offset)
         {
-            return I;
-        }
+            if (target.Length - offset < m_digest.GetDigestSize())
+                throw new ArgumentException("target length is less than digest size.", nameof(target));
 
-        public byte[] GetMasterSeed()
-        {
-            return masterSeed;
-        }
+            int q = Q, j = J;
 
+            m_digest.BlockUpdate(I, 0, I.Length);
 
-        public byte[] DeriveSeed(byte[] target, int offset)
-        {
-            if (target.Length < digest.GetDigestSize())
-            {
-                throw new ArgumentException("target length is less than digest size.");
-            }
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            Span<byte> qj = stackalloc byte[7];
+            Pack.UInt32_To_BE((uint)q, qj);
+            Pack.UInt16_To_BE((ushort)j, qj[4..]);
+            qj[6] = 0xFF;
+            m_digest.BlockUpdate(qj);
+#else
+            m_digest.Update((byte)(q >> 24));
+            m_digest.Update((byte)(q >> 16));
+            m_digest.Update((byte)(q >> 8));
+            m_digest.Update((byte)(q));
 
-            digest.BlockUpdate(I, 0, I.Length);
-            digest.Update((byte)(q >> 24));
-            digest.Update((byte)(q >> 16));
-            digest.Update((byte)(q >> 8));
-            digest.Update((byte)(q));
+            m_digest.Update((byte)(j >> 8));
+            m_digest.Update((byte)(j));
+            m_digest.Update(0xFF);
+#endif
 
-            digest.Update((byte)(j >> 8));
-            digest.Update((byte)(j));
-            digest.Update((byte)0xFF);
-            digest.BlockUpdate(masterSeed, 0, masterSeed.Length);
+            m_digest.BlockUpdate(m_masterSeed, 0, m_masterSeed.Length);
 
-            digest.DoFinal(target, offset); // Digest resets here.
-
-            return target;
-        }
-
-        public void deriveSeed(byte[] target, bool incJ)
-        {
-            deriveSeed(target, incJ, 0);
-        }
-
-
-        public void deriveSeed(byte[] target, bool incJ, int offset)
-        {
-
-            DeriveSeed(target, offset);
+            m_digest.DoFinal(target, offset); // Digest resets here.
 
             if (incJ)
             {
-                j++;
+                ++J;
             }
 
+            return target;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/sphincsplus/Adrs.cs b/crypto/src/pqc/crypto/sphincsplus/Adrs.cs
index 229fe8133..6c22a9d78 100644
--- a/crypto/src/pqc/crypto/sphincsplus/Adrs.cs
+++ b/crypto/src/pqc/crypto/sphincsplus/Adrs.cs
@@ -83,12 +83,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
 
             Arrays.Fill(value, 20, value.Length, (byte) 0);
         }
-        
+
         public void ChangeType(uint type)
         {
             Pack.UInt32_To_BE(type, value, OFFSET_TYPE);
         }
 
+        // FIXME
         public new uint GetType()
         {
             return Pack.BE_To_UInt32(value, OFFSET_TYPE);
diff --git a/crypto/src/pqc/crypto/utils/PrivateKeyInfoFactory.cs b/crypto/src/pqc/crypto/utils/PrivateKeyInfoFactory.cs
index 42bc3ca91..2768ad6f1 100644
--- a/crypto/src/pqc/crypto/utils/PrivateKeyInfoFactory.cs
+++ b/crypto/src/pqc/crypto/utils/PrivateKeyInfoFactory.cs
@@ -56,7 +56,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
                 HSSPrivateKeyParameters parameters = (HSSPrivateKeyParameters)privateKey;
 
                 byte[] encoding = Composer.Compose().U32Str(parameters.L).Bytes(parameters).Build();
-                byte[] pubEncoding = Composer.Compose().U32Str(parameters.L).Bytes(parameters.GetPublicKey().GetLmsPublicKey()).Build();
+                byte[] pubEncoding = Composer.Compose().U32Str(parameters.L).Bytes(parameters.GetPublicKey().LmsPublicKey).Build();
 
                 AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdAlgHssLmsHashsig);
                 return new PrivateKeyInfo(algorithmIdentifier, new DerOctetString(encoding), attributes, pubEncoding);
diff --git a/crypto/test/src/pqc/crypto/lms/HSSTests.cs b/crypto/test/src/pqc/crypto/lms/HSSTests.cs
index 53491f2a3..240e29c77 100644
--- a/crypto/test/src/pqc/crypto/lms/HSSTests.cs
+++ b/crypto/test/src/pqc/crypto/lms/HSSTests.cs
@@ -77,7 +77,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
             HSSPublicKeyParameters publicKey = HSSPublicKeyParameters.GetInstance(blocks[0]);
             byte[] message = (byte[]) blocks[1];
-            HSSSignature signature = HSSSignature.GetInstance(blocks[2], publicKey.GetL());
+            HSSSignature signature = HSSSignature.GetInstance(blocks[2], publicKey.L);
             Assert.True(HSS.VerifySignature(publicKey, signature, message), "Test Case 1 ");
         }
 
@@ -93,9 +93,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             var blocks = LoadVector("pqc.lms.testcase_2.txt");
 
             HSSPublicKeyParameters publicKey = HSSPublicKeyParameters.GetInstance(blocks[0]);
-            byte[] message = blocks[1] as byte[];
-            byte[] sig = blocks[2] as byte[];
-            HSSSignature signature = HSSSignature.GetInstance(sig, publicKey.GetL());
+            byte[] message = blocks[1];
+            byte[] sig = blocks[2];
+            HSSSignature signature = HSSSignature.GetInstance(sig, publicKey.L);
             Assert.True(HSS.VerifySignature(publicKey, signature, message), "Test Case 2 Signature");
 
             LMSPublicKeyParameters lmsPub = LMSPublicKeyParameters.GetInstance(blocks[3]);
@@ -145,8 +145,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         {
             byte[] seed = Hex.Decode("558b8966c48ae9cb898b423c83443aae014a72f1b1ab5cc85cf1d892903b5439");
             int level = 0;
-            LMSPrivateKeyParameters lmsPrivateKey = LMS.GenerateKeys(LMSigParameters.GetParametersForType(6),
-                LMOtsParameters.GetParametersForType(3), level, Hex.Decode("d08fabd4a2091ff0a8cb4ed834e74534"), seed);
+            LMSPrivateKeyParameters lmsPrivateKey = LMS.GenerateKeys(LMSigParameters.GetParametersByID(6),
+                LMOtsParameters.GetParametersByID(3), level, Hex.Decode("d08fabd4a2091ff0a8cb4ed834e74534"), seed);
             LMSPublicKeyParameters publicKey = lmsPrivateKey.GetPublicKey();
             Assert.True(Arrays.AreEqual(publicKey.GetT1(),
                 Hex.Decode("32a58885cd9ba0431235466bff9651c6c92124404d45fa53cf161c28f1ad5a8e")));
@@ -164,8 +164,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
         {
             byte[] seed = Hex.Decode("a1c4696e2608035a886100d05cd99945eb3370731884a8235e2fb3d4d71f2547");
             int level = 1;
-            LMSPrivateKeyParameters lmsPrivateKey = LMS.GenerateKeys(LMSigParameters.GetParametersForType(5),
-                LMOtsParameters.GetParametersForType(4), level, Hex.Decode("215f83b7ccb9acbcd08db97b0d04dc2b"), seed);
+            LMSPrivateKeyParameters lmsPrivateKey = LMS.GenerateKeys(LMSigParameters.GetParametersByID(5),
+                LMOtsParameters.GetParametersByID(4), level, Hex.Decode("215f83b7ccb9acbcd08db97b0d04dc2b"), seed);
             LMSPublicKeyParameters publicKey = lmsPrivateKey.GetPublicKey();
             Assert.True(Arrays.AreEqual(publicKey.GetT1(),
                 Hex.Decode("a1cd035833e0e90059603f26e07ad2aad152338e7a5e5984bcd5f7bb4eba40b7")));
@@ -243,8 +243,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                     //
                     // Check the private keys can be encoded and are the same.
                     //
-                    byte[] pk1 = (keyPair.GetKeys()[t] as LMSPrivateKeyParameters).GetEncoded();
-                    byte[] pk2 = (regenKeyPair.GetKeys()[t] as LMSPrivateKeyParameters).GetEncoded();
+                    byte[] pk1 = keyPair.GetKeys()[t].GetEncoded();
+                    byte[] pk2 = regenKeyPair.GetKeys()[t].GetEncoded();
                     Assert.True(Arrays.AreEqual(pk1, pk2));
 
                     //
@@ -287,8 +287,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                     //
                     // Check the private keys can be encoded and are not the same.
                     //
-                    byte[] pk1 = (keyPair.GetKeys()[t] as LMSPrivateKeyParameters).GetEncoded();
-                    byte[] pk2 = (differentKey.GetKeys()[t] as LMSPrivateKeyParameters).GetEncoded();
+                    byte[] pk1 = keyPair.GetKeys()[t].GetEncoded();
+                    byte[] pk2 = differentKey.GetKeys()[t].GetEncoded();
                     Assert.False(Arrays.AreEqual(pk1, pk2), "keys not the same");
 
                     //
@@ -343,12 +343,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                 else if (line.StartsWith("LMType:"))
                 {
                     int typ = int.Parse(line.Substring("LMType:".Length).Trim());
-                    lmsParameters.Add(LMSigParameters.GetParametersForType(typ));
+                    lmsParameters.Add(LMSigParameters.GetParametersByID(typ));
                 }
                 else if (line.StartsWith("LMOtsType:"))
                 {
                     int typ = int.Parse(line.Substring("LMOtsType:".Length).Trim());
-                    lmOtsParameters.Add(LMOtsParameters.GetParametersForType(typ));
+                    lmOtsParameters.Add(LMOtsParameters.GetParametersByID(typ));
                 }
                 else if (line.StartsWith("Rand:"))
                 {
@@ -385,8 +385,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
                     for (int i = 0; i != lmsParameters.Count; i++)
                     {
-                        lmsParams.Add(new LMSParameters(lmsParameters[i] as LMSigParameters,
-                            lmOtsParameters[i] as LMOtsParameters));
+                        lmsParams.Add(new LMSParameters(lmsParameters[i], lmOtsParameters[i]));
                     }
 
                     //
@@ -482,12 +481,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                     else if (line.StartsWith("LMType:"))
                     {
                         int typ = int.Parse(line.Substring("LMType:".Length).Trim());
-                        lmsParameters.Add(LMSigParameters.GetParametersForType(typ));
+                        lmsParameters.Add(LMSigParameters.GetParametersByID(typ));
                     }
                     else if (line.StartsWith("LMOtsType:"))
                     {
                         int typ = int.Parse(line.Substring("LMOtsType:".Length).Trim());
-                        lmOtsParameters.Add(LMOtsParameters.GetParametersForType(typ));
+                        lmOtsParameters.Add(LMOtsParameters.GetParametersByID(typ));
                     }
                     else if (line.StartsWith("Rand:"))
                     {
@@ -519,15 +518,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
                 for (int i = 0; i != lmsParameters.Count; i++)
                 {
-                    lmsParams.Add(new LMSParameters(lmsParameters[i] as LMSigParameters,
-                        lmOtsParameters[i] as LMOtsParameters));
+                    lmsParams.Add(new LMSParameters(lmsParameters[i], lmOtsParameters[i]));
                 }
 
                 LMSParameters[] lmsParamsArray = new LMSParameters[lmsParams.Count];
                 lmsParams.CopyTo(lmsParamsArray, 0);
                 HSSPrivateKeyParameters keyPair = HSS.GenerateHssKeyPair(
-                    new HSSKeyGenerationParameters(
-                        lmsParamsArray, fixRnd)
+                    new HSSKeyGenerationParameters(lmsParamsArray, fixRnd)
                 );
 
                 Assert.True(Arrays.AreEqual(hssPubEnc, keyPair.GetPublicKey().GetEncoded()));
@@ -579,7 +576,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                         Assert.True(HSS.VerifySignature(pubKeyGenerated, sigCalculated, message));
 
                         HSSSignature sigFromVector = HSSSignature.GetInstance((byte[]) sigVectors[c],
-                            pubKeyFromVector.GetL());
+                            pubKeyFromVector.L);
 
                         Assert.True(HSS.VerifySignature(pubKeyFromVector, sigFromVector, message));
                         Assert.True(HSS.VerifySignature(pubKeyGenerated, sigFromVector, message));
@@ -616,7 +613,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             );
 
 
-            LMSPrivateKeyParameters lmsKey = keyPair.GetKeys()[keyPair.L - 1] as LMSPrivateKeyParameters;
+            LMSPrivateKeyParameters lmsKey = keyPair.GetKeys()[keyPair.L - 1];
             //
             // There should be a max of 32768 signatures for this key.
             //
@@ -659,7 +656,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             //
             // This should trigger the generation of a new key.
             //
-            LMSPrivateKeyParameters potentialNewLMSKey = keyPair.GetKeys()[keyPair.L - 1] as LMSPrivateKeyParameters;
+            LMSPrivateKeyParameters potentialNewLMSKey = keyPair.GetKeys()[keyPair.L - 1];
             Assert.False(potentialNewLMSKey.Equals(lmsKey));
         }
 
@@ -791,10 +788,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                         Pack_Int32_To_BE(ctr, message, 0);
                         HSSSignature sig = HSS.GenerateSignature(keyPair, message);
 
-                        Assert.True(ctr % 1024 == sig.GetSignature().GetQ());
+                        Assert.True(ctr % 1024 == sig.Signature.Q);
 
                         // Check there was a post increment in the tail end LMS key.
-                        Assert.True((ctr % 1024) + 1 == (keyPair.GetKeys()[keyPair.L - 1] as LMSPrivateKeyParameters).GetIndex());
+                        Assert.True((ctr % 1024) + 1 == keyPair.GetKeys()[keyPair.L - 1].GetIndex());
 
                         Assert.True(ctr + 1 == keyPair.GetIndex());
 
@@ -806,21 +803,19 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
                         for (int t = keyPair.GetKeys().Count - 1; t >= 0; t--)
                         {
-                            LMSigParameters sigParameters = (keyPair.GetKeys()[t] as LMSPrivateKeyParameters).GetSigParameters();
-                            int mask = (1 << sigParameters.GetH()) - 1;
+                            LMSigParameters sigParameters = keyPair.GetKeys()[t].GetSigParameters();
+                            int mask = (1 << sigParameters.H) - 1;
                             qValues[t] = q & mask;
-                            q >>= sigParameters.GetH();
+                            q >>= sigParameters.H;
                         }
 
                         for (int t = 0; t < keyPair.GetKeys().Count; t++)
                         {
-                            Assert.True( (keyPair.GetKeys()[t] as LMSPrivateKeyParameters).GetIndex() - 1 == qValues[t]);
+                            Assert.True(keyPair.GetKeys()[t].GetIndex() - 1 == qValues[t]);
                         }
 
-
                         Assert.True(HSS.VerifySignature(pk, sig, message));
-                        Assert.True(sig.GetSignature().GetParameter().GetType() ==
-                                    LMSigParameters.lms_sha256_n32_h10.GetType());
+                        Assert.True(sig.Signature.SigParameters.ID == LMSigParameters.lms_sha256_n32_h10.ID);
 
                         {
                             //
@@ -828,7 +823,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
                             //
                             byte[] rawSig = sig.GetEncoded();
                             rawSig[100] ^= 1;
-                            HSSSignature parsedSig = HSSSignature.GetInstance(rawSig, pk.GetL());
+                            HSSSignature parsedSig = HSSSignature.GetInstance(rawSig, pk.L);
                             Assert.False(HSS.VerifySignature(pk, parsedSig, message));
 
                             try
diff --git a/crypto/test/src/pqc/crypto/lms/LMSKeyGenTests.cs b/crypto/test/src/pqc/crypto/lms/LMSKeyGenTests.cs
index 8695fe019..30df5d5d1 100644
--- a/crypto/test/src/pqc/crypto/lms/LMSKeyGenTests.cs
+++ b/crypto/test/src/pqc/crypto/lms/LMSKeyGenTests.cs
@@ -33,7 +33,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             int level = 1; // This is the second level, we use this because it signs the message.
 
             // Generate the private key.
-            LMSPrivateKeyParameters lmsPrivateKey = LMS.GenerateKeys(LMSigParameters.GetParametersForType(5), LMOtsParameters.GetParametersForType(4), level, I, seed);
+            LMSPrivateKeyParameters lmsPrivateKey = LMS.GenerateKeys(LMSigParameters.GetParametersByID(5),
+                LMOtsParameters.GetParametersByID(4), level, I, seed);
 
             // This derives the public key.
             LMSPublicKeyParameters publicKey = lmsPrivateKey.GetPublicKey();
diff --git a/crypto/test/src/pqc/crypto/lms/LMSTests.cs b/crypto/test/src/pqc/crypto/lms/LMSTests.cs
index dbc541674..721d58160 100644
--- a/crypto/test/src/pqc/crypto/lms/LMSTests.cs
+++ b/crypto/test/src/pqc/crypto/lms/LMSTests.cs
@@ -31,7 +31,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             byte[] I = Hex.Decode("d08fabd4a2091ff0a8cb4ed834e74534");
 
             LMOtsPrivateKey privateKey = new LMOtsPrivateKey(parameter, I, 0, seed);
-            LMOtsPublicKey publicKey = LM_OTS.lms_ots_generatePublicKey(privateKey);
+            LMOtsPublicKey publicKey = LM_OTS.LmsOtsGeneratePublicKey(privateKey);
 
             byte[] ms = new byte[32];
             for (int t = 0; t < ms.Length; t++)
@@ -43,24 +43,24 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             
             ctx.BlockUpdate(ms, 0, ms.Length);
 
-            LMOtsSignature sig = LM_OTS.lm_ots_generate_signature(privateKey, ctx.GetQ(), ctx.C);
-            Assert.True(LM_OTS.lm_ots_validate_signature(publicKey, sig, ms, false));
+            LMOtsSignature sig = LM_OTS.LMOtsGenerateSignature(privateKey, ctx.GetQ(), ctx.C);
+            Assert.True(LM_OTS.LMOtsValidateSignature(publicKey, sig, ms, false));
 
             //  Vandalise signature
             {
 
                 byte[] vandalisedSignature = sig.GetEncoded(); // Arrays.clone(sig);
                 vandalisedSignature[256] ^= 1; // Single bit error
-                Assert.False(LM_OTS.lm_ots_validate_signature(publicKey, LMOtsSignature.GetInstance(vandalisedSignature), ms, false));
+                Assert.False(LM_OTS.LMOtsValidateSignature(publicKey, LMOtsSignature.GetInstance(vandalisedSignature), ms, false));
             }
 
             // Vandalise public key.
             {
                 byte[] vandalisedPubKey = Arrays.Clone(publicKey.GetEncoded());
                 vandalisedPubKey[50] ^= 1;
-                Assert.False(LM_OTS.lm_ots_validate_signature(LMOtsPublicKey.GetInstance(vandalisedPubKey), sig, ms, false));
+                Assert.False(LM_OTS.LMOtsValidateSignature(LMOtsPublicKey.GetInstance(vandalisedPubKey), sig, ms, false));
             }
-            
+
             //
             // check incorrect alg type is detected.
             //
@@ -68,14 +68,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             {
                 byte[] vandalisedPubKey = Arrays.Clone(publicKey.GetEncoded());
                 vandalisedPubKey[3] += 1;
-                LM_OTS.lm_ots_validate_signature(LMOtsPublicKey.GetInstance(vandalisedPubKey), sig, ms, false);
+                LM_OTS.LMOtsValidateSignature(LMOtsPublicKey.GetInstance(vandalisedPubKey), sig, ms, false);
                 Assert.True(false, "Must fail as public key type not match signature type.");
             }
             catch (LMSException ex)
             {
                 Assert.True(ex.Message.Contains("public key and signature ots types do not match"));
             }
-            
         }
 
         [Test]
@@ -94,10 +93,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             byte[] seed = Hex.Decode("a1c4696e2608035a886100d05cd99945eb3370731884a8235e2fb3d4d71f2547");
             int level = 1;
             LMSPrivateKeyParameters lmsPrivateKey = LMS.GenerateKeys(
-                LMSigParameters.GetParametersForType(5),
-                LMOtsParameters.GetParametersForType(4),
+                LMSigParameters.GetParametersByID(5),
+                LMOtsParameters.GetParametersByID(4),
                 level, Hex.Decode("215f83b7ccb9acbcd08db97b0d04dc2b"), seed);
-            
+
             LMSPublicKeyParameters publicKey = lmsPrivateKey.GetPublicKey();
 
             lmsPrivateKey.ExtractKeyShard(3);
@@ -138,7 +137,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
             byte[] I = Hex.Decode("d08fabd4a2091ff0a8cb4ed834e74534");
 
             LMOtsPrivateKey privateKey = new LMOtsPrivateKey(parameter, I, 0, seed);
-            LMOtsPublicKey publicKey = LM_OTS.lms_ots_generatePublicKey(privateKey);
+            LMOtsPublicKey publicKey = LM_OTS.LmsOtsGeneratePublicKey(privateKey);
 
             byte[] ms = new byte[32];
                 for (int t = 0; t < ms.Length; t++)
@@ -150,8 +149,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
 
             ctx.BlockUpdate(ms, 0, ms.Length);
 
-            LMOtsSignature sig = LM_OTS.lm_ots_generate_signature(privateKey, ctx.GetQ(), ctx.C);
-            Assert.True(LM_OTS.lm_ots_validate_signature(publicKey, sig, ms, false));
+            LMOtsSignature sig = LM_OTS.LMOtsGenerateSignature(privateKey, ctx.GetQ(), ctx.C);
+            Assert.True(LM_OTS.LMOtsValidateSignature(publicKey, sig, ms, false));
 
             try
             {
diff --git a/crypto/test/src/pqc/crypto/test/HSSTest.cs b/crypto/test/src/pqc/crypto/test/HSSTest.cs
index 25a5fff3f..678f1cbab 100644
--- a/crypto/test/src/pqc/crypto/test/HSSTest.cs
+++ b/crypto/test/src/pqc/crypto/test/HSSTest.cs
@@ -55,10 +55,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests
 
             HSSPublicKeyParameters pubKey = (HSSPublicKeyParameters)kp.Public;
             
-            LMSParameters lmsParam = pubKey.GetLmsPublicKey().GetLmsParameters();
+            LMSParameters lmsParam = pubKey.LmsPublicKey.GetLmsParameters();
 
-            Assert.AreEqual(LMSigParameters.lms_sha256_n32_h5, lmsParam.GetLmSigParam());
-            Assert.AreEqual(LMOtsParameters.sha256_n32_w4, lmsParam.GetLmotsParam());
+            Assert.AreEqual(LMSigParameters.lms_sha256_n32_h5, lmsParam.LMSigParameters);
+            Assert.AreEqual(LMOtsParameters.sha256_n32_w4, lmsParam.LMOtsParameters);
 
             HSSSigner signer = new HSSSigner();