diff options
Diffstat (limited to 'crypto/src')
30 files changed, 650 insertions, 943 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); |