<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.0" />

Hss

public static class Hss
using Org.BouncyCastle.Security; using System; using System.Collections.Generic; namespace Org.BouncyCastle.Pqc.Crypto.Lms { public static class Hss { public static HssPrivateKeyParameters GenerateHssKeyPair(HssKeyGenerationParameters parameters) { LmsPrivateKeyParameters[] array = new LmsPrivateKeyParameters[parameters.Depth]; LmsSignature[] collection = new LmsSignature[parameters.Depth - 1]; byte[] nextBytes = SecureRandom.GetNextBytes(parameters.Random, parameters.GetLmsParameters(0).LMSigParameters.M); byte[] nextBytes2 = SecureRandom.GetNextBytes(parameters.Random, 16); byte[] array2 = new byte[0]; long num = 1; for (int i = 0; i < array.Length; i++) { LmsParameters lmsParameters = parameters.GetLmsParameters(i); if (i == 0) array[i] = new LmsPrivateKeyParameters(lmsParameters.LMSigParameters, lmsParameters.LMOtsParameters, 0, nextBytes2, 1 << lmsParameters.LMSigParameters.H, nextBytes, false); else array[i] = new LmsPrivateKeyParameters(lmsParameters.LMSigParameters, lmsParameters.LMOtsParameters, -1, array2, 1 << lmsParameters.LMSigParameters.H, array2, true); num <<= lmsParameters.LMSigParameters.H; } if (num == 0) num = 9223372036854775807; return new HssPrivateKeyParameters(parameters.Depth, new List<LmsPrivateKeyParameters>(array), new List<LmsSignature>(collection), 0, num); } public static void IncrementIndex(HssPrivateKeyParameters keyPair) { lock (keyPair) { RangeTestKeys(keyPair); keyPair.IncIndex(); keyPair.GetKeys()[keyPair.Level - 1].IncIndex(); } } public static void RangeTestKeys(HssPrivateKeyParameters keyPair) { lock (keyPair) { if (keyPair.GetIndex() >= keyPair.IndexLimit) throw new Exception("hss private key" + (keyPair.IsShard() ? " shard" : "") + " is exhausted"); int level = keyPair.Level; int num = level; IList<LmsPrivateKeyParameters> keys = keyPair.GetKeys(); while (keys[num - 1].GetIndex() == 1 << keys[num - 1].SigParameters.H) { if (--num == 0) throw new Exception("hss private key" + (keyPair.IsShard() ? " shard" : "") + " is exhausted the maximum limit for this HSS private key"); } while (num < level) { keyPair.ReplaceConsumedKey(num++); } } } public static HssSignature GenerateSignature(HssPrivateKeyParameters keyPair, byte[] message) { int level = keyPair.Level; LmsPrivateKeyParameters lmsPrivateKeyParameters = default(LmsPrivateKeyParameters); LmsSignedPubKey[] array = default(LmsSignedPubKey[]); lock (keyPair) { RangeTestKeys(keyPair); IList<LmsPrivateKeyParameters> keys = keyPair.GetKeys(); IList<LmsSignature> sig = keyPair.GetSig(); lmsPrivateKeyParameters = keyPair.GetKeys()[level - 1]; int i = 0; array = new LmsSignedPubKey[level - 1]; for (; i < level - 1; i++) { array[i] = new LmsSignedPubKey(sig[i], keys[i + 1].GetPublicKey()); } keyPair.IncIndex(); } LmsContext lmsContext = lmsPrivateKeyParameters.GenerateLmsContext().WithSignedPublicKeys(array); lmsContext.BlockUpdate(message, 0, message.Length); return GenerateSignature(level, lmsContext); } public static HssSignature GenerateSignature(int L, LmsContext context) { return new HssSignature(L - 1, context.SignedPubKeys, Lms.GenerateSign(context)); } public static bool VerifySignature(HssPublicKeyParameters publicKey, HssSignature signature, byte[] message) { int lMinus = signature.LMinus1; if (lMinus + 1 != publicKey.Level) return false; LmsSignature[] array = new LmsSignature[lMinus + 1]; LmsPublicKeyParameters[] array2 = new LmsPublicKeyParameters[lMinus]; for (int i = 0; i < lMinus; i++) { array[i] = signature.SignedPubKeys[i].Signature; array2[i] = signature.SignedPubKeys[i].PublicKey; } array[lMinus] = signature.Signature; LmsPublicKeyParameters publicKey2 = publicKey.LmsPublicKey; for (int j = 0; j < lMinus; j++) { LmsSignature s = array[j]; byte[] message2 = array2[j].ToByteArray(); if (!Lms.VerifySignature(publicKey2, s, message2)) return false; try { publicKey2 = array2[j]; } catch (Exception ex) { throw new Exception(ex.Message, ex); } } return Lms.VerifySignature(publicKey2, array[lMinus], message); } } }