<PackageReference Include="BouncyCastle.Cryptography" Version="2.7.0-beta.98" />

PqcPublicKeyFactory

public static class PqcPublicKeyFactory
using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.BC; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Pqc.Asn1; using Org.BouncyCastle.Pqc.Crypto.Bike; using Org.BouncyCastle.Pqc.Crypto.Cmce; using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; using Org.BouncyCastle.Pqc.Crypto.Falcon; using Org.BouncyCastle.Pqc.Crypto.Frodo; using Org.BouncyCastle.Pqc.Crypto.Hqc; using Org.BouncyCastle.Pqc.Crypto.Lms; using Org.BouncyCastle.Pqc.Crypto.Ntru; using Org.BouncyCastle.Pqc.Crypto.Picnic; using Org.BouncyCastle.Pqc.Crypto.Saber; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Utilities; using System; using System.Collections.Generic; using System.IO; namespace Org.BouncyCastle.Pqc.Crypto.Utilities { public static class PqcPublicKeyFactory { private delegate AsymmetricKeyParameter Converter (SubjectPublicKeyInfo keyInfo, object defaultParams); private static Dictionary<DerObjectIdentifier, Converter> Converters; static PqcPublicKeyFactory() { Converters = new Dictionary<DerObjectIdentifier, Converter>(); Converters[PkcsObjectIdentifiers.IdAlgHssLmsHashsig] = LmsConverter; Converters[BCObjectIdentifiers.mceliece348864_r3] = CmceConverter; Converters[BCObjectIdentifiers.mceliece348864f_r3] = CmceConverter; Converters[BCObjectIdentifiers.mceliece460896_r3] = CmceConverter; Converters[BCObjectIdentifiers.mceliece460896f_r3] = CmceConverter; Converters[BCObjectIdentifiers.mceliece6688128_r3] = CmceConverter; Converters[BCObjectIdentifiers.mceliece6688128f_r3] = CmceConverter; Converters[BCObjectIdentifiers.mceliece6960119_r3] = CmceConverter; Converters[BCObjectIdentifiers.mceliece6960119f_r3] = CmceConverter; Converters[BCObjectIdentifiers.mceliece8192128_r3] = CmceConverter; Converters[BCObjectIdentifiers.mceliece8192128f_r3] = CmceConverter; Converters[BCObjectIdentifiers.frodokem640aes] = FrodoConverter; Converters[BCObjectIdentifiers.frodokem640shake] = FrodoConverter; Converters[BCObjectIdentifiers.frodokem976aes] = FrodoConverter; Converters[BCObjectIdentifiers.frodokem976shake] = FrodoConverter; Converters[BCObjectIdentifiers.frodokem1344aes] = FrodoConverter; Converters[BCObjectIdentifiers.frodokem1344shake] = FrodoConverter; Converters[BCObjectIdentifiers.lightsaberkem128r3] = SaberConverter; Converters[BCObjectIdentifiers.saberkem128r3] = SaberConverter; Converters[BCObjectIdentifiers.firesaberkem128r3] = SaberConverter; Converters[BCObjectIdentifiers.lightsaberkem192r3] = SaberConverter; Converters[BCObjectIdentifiers.saberkem192r3] = SaberConverter; Converters[BCObjectIdentifiers.firesaberkem192r3] = SaberConverter; Converters[BCObjectIdentifiers.lightsaberkem256r3] = SaberConverter; Converters[BCObjectIdentifiers.saberkem256r3] = SaberConverter; Converters[BCObjectIdentifiers.firesaberkem256r3] = SaberConverter; Converters[BCObjectIdentifiers.ulightsaberkemr3] = SaberConverter; Converters[BCObjectIdentifiers.usaberkemr3] = SaberConverter; Converters[BCObjectIdentifiers.ufiresaberkemr3] = SaberConverter; Converters[BCObjectIdentifiers.lightsaberkem90sr3] = SaberConverter; Converters[BCObjectIdentifiers.saberkem90sr3] = SaberConverter; Converters[BCObjectIdentifiers.firesaberkem90sr3] = SaberConverter; Converters[BCObjectIdentifiers.ulightsaberkem90sr3] = SaberConverter; Converters[BCObjectIdentifiers.usaberkem90sr3] = SaberConverter; Converters[BCObjectIdentifiers.ufiresaberkem90sr3] = SaberConverter; Converters[BCObjectIdentifiers.picnic] = PicnicConverter; Converters[BCObjectIdentifiers.picnicl1fs] = PicnicConverter; Converters[BCObjectIdentifiers.picnicl1ur] = PicnicConverter; Converters[BCObjectIdentifiers.picnicl3fs] = PicnicConverter; Converters[BCObjectIdentifiers.picnicl3ur] = PicnicConverter; Converters[BCObjectIdentifiers.picnicl5fs] = PicnicConverter; Converters[BCObjectIdentifiers.picnicl5ur] = PicnicConverter; Converters[BCObjectIdentifiers.picnic3l1] = PicnicConverter; Converters[BCObjectIdentifiers.picnic3l3] = PicnicConverter; Converters[BCObjectIdentifiers.picnic3l5] = PicnicConverter; Converters[BCObjectIdentifiers.picnicl1full] = PicnicConverter; Converters[BCObjectIdentifiers.picnicl3full] = PicnicConverter; Converters[BCObjectIdentifiers.picnicl5full] = PicnicConverter; Converters.Add(BCObjectIdentifiers.ntruhps2048509, NtruConverter); Converters.Add(BCObjectIdentifiers.ntruhps2048677, NtruConverter); Converters.Add(BCObjectIdentifiers.ntruhps4096821, NtruConverter); Converters.Add(BCObjectIdentifiers.ntruhps40961229, NtruConverter); Converters.Add(BCObjectIdentifiers.ntruhrss701, NtruConverter); Converters.Add(BCObjectIdentifiers.ntruhrss1373, NtruConverter); Converters[BCObjectIdentifiers.dilithium2] = DilithiumConverter; Converters[BCObjectIdentifiers.dilithium3] = DilithiumConverter; Converters[BCObjectIdentifiers.dilithium5] = DilithiumConverter; Converters[BCObjectIdentifiers.dilithium2_aes] = DilithiumConverter; Converters[BCObjectIdentifiers.dilithium3_aes] = DilithiumConverter; Converters[BCObjectIdentifiers.dilithium5_aes] = DilithiumConverter; Converters[BCObjectIdentifiers.falcon_512] = FalconConverter; Converters[BCObjectIdentifiers.falcon_1024] = FalconConverter; Converters[BCObjectIdentifiers.bike128] = BikeConverter; Converters[BCObjectIdentifiers.bike192] = BikeConverter; Converters[BCObjectIdentifiers.bike256] = BikeConverter; Converters[BCObjectIdentifiers.hqc128] = HqcConverter; Converters[BCObjectIdentifiers.hqc192] = HqcConverter; Converters[BCObjectIdentifiers.hqc256] = HqcConverter; Converters[BCObjectIdentifiers.sphincsPlus] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_sha2_128s_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_sha2_128f_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_shake_128s_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_shake_128f_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_haraka_128s_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_haraka_128f_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_sha2_192s_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_sha2_192f_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_shake_192s_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_shake_192f_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_haraka_192s_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_haraka_192f_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_sha2_256s_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_sha2_256f_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_shake_256s_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_shake_256f_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_haraka_256s_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_haraka_256f_r3] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_haraka_128f_r3_simple] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_haraka_128s_r3_simple] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_haraka_192f_r3_simple] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_haraka_192s_r3_simple] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_haraka_256f_r3_simple] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_haraka_256s_r3_simple] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_sha2_128s] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_sha2_128f] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_shake_128s] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_shake_128f] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_sha2_192s] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_sha2_192f] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_shake_192s] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_shake_192f] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_sha2_256s] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_sha2_256f] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_shake_256s] = SphincsPlusConverter; Converters[BCObjectIdentifiers.sphincsPlus_shake_256f] = SphincsPlusConverter; } public static AsymmetricKeyParameter CreateKey(byte[] keyInfoData) { return CreateKey(SubjectPublicKeyInfo.GetInstance(keyInfoData)); } public static AsymmetricKeyParameter CreateKey(Stream inStr) { return CreateKey(SubjectPublicKeyInfo.GetInstance(Asn1Object.FromStream(inStr))); } public static AsymmetricKeyParameter CreateKey(SubjectPublicKeyInfo keyInfo) { return CreateKey(keyInfo, null); } public static AsymmetricKeyParameter CreateKey(SubjectPublicKeyInfo keyInfo, object defaultParams) { DerObjectIdentifier algorithm = keyInfo.Algorithm.Algorithm; if (!Converters.TryGetValue(algorithm, out Converter value)) throw new IOException("algorithm identifier in public key not recognised: " + algorithm?.ToString()); return value(keyInfo, defaultParams); } internal static DilithiumPublicKeyParameters GetDilithiumPublicKey(DilithiumParameters dilithiumParameters, DerBitString publicKeyData) { byte[] octets = publicKeyData.GetOctets(); try { Asn1Object asn1Object = Asn1Object.FromByteArray(octets); Asn1Sequence asn1Sequence = asn1Object as Asn1Sequence; if (asn1Sequence == null) { byte[] octets2 = Asn1OctetString.GetInstance(asn1Object).GetOctets(); return new DilithiumPublicKeyParameters(dilithiumParameters, octets2); } return new DilithiumPublicKeyParameters(dilithiumParameters, Asn1OctetString.GetInstance(asn1Sequence[0]).GetOctets(), Asn1OctetString.GetInstance(asn1Sequence[1]).GetOctets()); } catch (Exception) { return new DilithiumPublicKeyParameters(dilithiumParameters, octets); } } private static AsymmetricKeyParameter LmsConverter(SubjectPublicKeyInfo keyInfo, object defaultParams) { DerBitString publicKey = keyInfo.PublicKey; if (publicKey.IsOctetAligned()) { try { Asn1OctetString asn1OctetString = Asn1Object.FromMemoryStream(publicKey.GetOctetMemoryStream()) as Asn1OctetString; if (asn1OctetString != null) return GetLmsKeyParameters(asn1OctetString.GetOctets()); } catch (Exception) { } return GetLmsKeyParameters(publicKey.GetOctets()); } throw new ArgumentException("invalid LMS public key"); } private static LmsKeyParameters GetLmsKeyParameters(byte[] keyEnc) { if (keyEnc.Length >= 4 && Pack.BE_To_UInt32(keyEnc, 0) == 1) return LmsPublicKeyParameters.Parse(keyEnc, 4, keyEnc.Length - 4); return HssPublicKeyParameters.Parse(keyEnc); } private static AsymmetricKeyParameter SphincsPlusConverter(SubjectPublicKeyInfo keyInfo, object defaultParams) { try { byte[] octets = Asn1OctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets(); return new SphincsPlusPublicKeyParameters(PqcUtilities.SphincsPlusParamsLookup(keyInfo.Algorithm.Algorithm), Arrays.CopyOfRange(octets, 4, octets.Length)); } catch (Exception) { byte[] octets2 = keyInfo.PublicKey.GetOctets(); return new SphincsPlusPublicKeyParameters(PqcUtilities.SphincsPlusParamsLookup(keyInfo.Algorithm.Algorithm), octets2); } } private static AsymmetricKeyParameter CmceConverter(SubjectPublicKeyInfo keyInfo, object defaultParams) { byte[] t = CmcePublicKey.GetInstance(keyInfo.ParsePublicKey()).T; return new CmcePublicKeyParameters(PqcUtilities.McElieceParamsLookup(keyInfo.Algorithm.Algorithm), t); } private static AsymmetricKeyParameter FrodoConverter(SubjectPublicKeyInfo keyInfo, object defaultParams) { byte[] octets = Asn1OctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets(); return new FrodoPublicKeyParameters(PqcUtilities.FrodoParamsLookup(keyInfo.Algorithm.Algorithm), octets); } private static AsymmetricKeyParameter SaberConverter(SubjectPublicKeyInfo keyInfo, object defaultParams) { byte[] octets = Asn1OctetString.GetInstance(Asn1Sequence.GetInstance(keyInfo.ParsePublicKey())[0]).GetOctets(); return new SaberPublicKeyParameters(PqcUtilities.SaberParamsLookup(keyInfo.Algorithm.Algorithm), octets); } private static AsymmetricKeyParameter PicnicConverter(SubjectPublicKeyInfo keyInfo, object defaultParams) { byte[] octets = Asn1OctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets(); return new PicnicPublicKeyParameters(PqcUtilities.PicnicParamsLookup(keyInfo.Algorithm.Algorithm), octets); } private static AsymmetricKeyParameter DilithiumConverter(SubjectPublicKeyInfo keyInfo, object defaultParams) { return GetDilithiumPublicKey(PqcUtilities.DilithiumParamsLookup(keyInfo.Algorithm.Algorithm), keyInfo.PublicKey); } private static AsymmetricKeyParameter NtruConverter(SubjectPublicKeyInfo keyInfo, object defaultParams) { return GetNtruPublicKey(PqcUtilities.NtruParamsLookup(keyInfo.Algorithm.Algorithm), keyInfo.PublicKey); } private static NtruPublicKeyParameters GetNtruPublicKey(NtruParameters ntruParameters, DerBitString publicKey) { if (publicKey.IsOctetAligned()) { int publicKeyLength = ntruParameters.PublicKeyLength; int bytesLength = publicKey.GetBytesLength(); if (bytesLength == publicKeyLength) return NtruPublicKeyParameters.FromEncoding(ntruParameters, publicKey.GetOctets()); if (bytesLength > publicKeyLength) try { Asn1OctetString asn1OctetString = Asn1Object.FromMemoryStream(publicKey.GetOctetMemoryStream()) as Asn1OctetString; if (asn1OctetString != null && asn1OctetString.GetOctetsLength() == publicKeyLength) return NtruPublicKeyParameters.FromEncoding(ntruParameters, asn1OctetString.GetOctets()); } catch (Exception) { } } throw new ArgumentException("invalid " + ntruParameters.Name + " public key"); } private static AsymmetricKeyParameter FalconConverter(SubjectPublicKeyInfo keyInfo, object defaultParams) { FalconParameters falconParameters = PqcUtilities.FalconParamsLookup(keyInfo.Algorithm.Algorithm); try { Asn1Object asn1Object = keyInfo.ParsePublicKey(); if (!(asn1Object is Asn1Sequence)) { byte[] octets = Asn1OctetString.GetInstance(asn1Object).GetOctets(); if (octets[0] != (byte)falconParameters.LogN) throw new ArgumentException("byte[] enc of Falcon h value not tagged correctly"); return new FalconPublicKeyParameters(falconParameters, Arrays.CopyOfRange(octets, 1, octets.Length)); } byte[] octets2 = Asn1OctetString.GetInstance(Asn1Sequence.GetInstance(asn1Object)[0]).GetOctets(); return new FalconPublicKeyParameters(falconParameters, octets2); } catch (Exception) { byte[] octets3 = keyInfo.PublicKey.GetOctets(); if (octets3[0] != (byte)falconParameters.LogN) throw new ArgumentException("byte[] enc of Falcon h value not tagged correctly"); return new FalconPublicKeyParameters(falconParameters, Arrays.CopyOfRange(octets3, 1, octets3.Length)); } } private static AsymmetricKeyParameter BikeConverter(SubjectPublicKeyInfo keyInfo, object defaultParams) { try { byte[] octets = Asn1OctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets(); return new BikePublicKeyParameters(PqcUtilities.BikeParamsLookup(keyInfo.Algorithm.Algorithm), octets); } catch (Exception) { byte[] octets2 = keyInfo.PublicKey.GetOctets(); return new BikePublicKeyParameters(PqcUtilities.BikeParamsLookup(keyInfo.Algorithm.Algorithm), octets2); } } private static AsymmetricKeyParameter HqcConverter(SubjectPublicKeyInfo keyInfo, object defaultParams) { try { byte[] octets = Asn1OctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets(); return new HqcPublicKeyParameters(PqcUtilities.HqcParamsLookup(keyInfo.Algorithm.Algorithm), octets); } catch (Exception) { byte[] octets2 = keyInfo.PublicKey.GetOctets(); return new HqcPublicKeyParameters(PqcUtilities.HqcParamsLookup(keyInfo.Algorithm.Algorithm), octets2); } } } }