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.Crystals.Kyber;
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.Picnic;
using Org.BouncyCastle.Pqc.Crypto.Saber;
using Org.BouncyCastle.Pqc.Crypto.Sike;
using Org.BouncyCastle.Pqc.Crypto.SphincsPlus;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
using System;
using System.Collections.Generic;
using System.IO;
namespace Org.BouncyCastle.Pqc.Crypto.Utilities
{
public static class PqcPublicKeyFactory
{
internal abstract class SubjectPublicKeyInfoConverter
{
internal abstract AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams);
}
private class LmsConverter : SubjectPublicKeyInfoConverter
{
internal override AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams)
{
byte[] array = Asn1OctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets();
if (Pack.BE_To_UInt32(array, 0) == 1)
return LmsPublicKeyParameters.GetInstance(Arrays.CopyOfRange(array, 4, array.Length));
if (array.Length == 64)
array = Arrays.CopyOfRange(array, 4, array.Length);
return HssPublicKeyParameters.GetInstance(array);
}
}
private class SphincsPlusConverter : SubjectPublicKeyInfoConverter
{
internal override AsymmetricKeyParameter GetPublicKeyParameters(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 class CmceConverter : SubjectPublicKeyInfoConverter
{
internal override AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams)
{
byte[] t = CmcePublicKey.GetInstance(keyInfo.ParsePublicKey()).T;
return new CmcePublicKeyParameters(PqcUtilities.McElieceParamsLookup(keyInfo.Algorithm.Algorithm), t);
}
}
private class FrodoConverter : SubjectPublicKeyInfoConverter
{
internal override AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams)
{
byte[] octets = Asn1OctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets();
return new FrodoPublicKeyParameters(PqcUtilities.FrodoParamsLookup(keyInfo.Algorithm.Algorithm), octets);
}
}
private class SaberConverter : SubjectPublicKeyInfoConverter
{
internal override AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams)
{
byte[] octets = Asn1OctetString.GetInstance(Asn1Sequence.GetInstance(keyInfo.ParsePublicKey())[0]).GetOctets();
return new SaberPublicKeyParameters(PqcUtilities.SaberParamsLookup(keyInfo.Algorithm.Algorithm), octets);
}
}
private class PicnicConverter : SubjectPublicKeyInfoConverter
{
internal override AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams)
{
byte[] octets = Asn1OctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets();
return new PicnicPublicKeyParameters(PqcUtilities.PicnicParamsLookup(keyInfo.Algorithm.Algorithm), octets);
}
}
[Obsolete("Will be removed")]
private class SikeConverter : SubjectPublicKeyInfoConverter
{
internal override AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams)
{
byte[] octets = Asn1OctetString.GetInstance(keyInfo.ParsePublicKey()).GetOctets();
return new SikePublicKeyParameters(PqcUtilities.SikeParamsLookup(keyInfo.Algorithm.Algorithm), octets);
}
}
internal class DilithiumConverter : SubjectPublicKeyInfoConverter
{
internal override AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams)
{
return GetPublicKeyParameters(PqcUtilities.DilithiumParamsLookup(keyInfo.Algorithm.Algorithm), keyInfo.PublicKey);
}
internal static DilithiumPublicKeyParameters GetPublicKeyParameters(DilithiumParameters dilithiumParameters, DerBitString publicKeyData)
{
try {
Asn1Object asn1Object = Asn1Object.FromByteArray(publicKeyData.GetOctets());
Asn1Sequence asn1Sequence = asn1Object as Asn1Sequence;
if (asn1Sequence == null) {
byte[] octets = Asn1OctetString.GetInstance(asn1Object).GetOctets();
return new DilithiumPublicKeyParameters(dilithiumParameters, octets);
}
return new DilithiumPublicKeyParameters(dilithiumParameters, Asn1OctetString.GetInstance(asn1Sequence[0]).GetOctets(), Asn1OctetString.GetInstance(asn1Sequence[1]).GetOctets());
} catch (Exception) {
return new DilithiumPublicKeyParameters(dilithiumParameters, publicKeyData.GetOctets());
}
}
}
private class KyberConverter : SubjectPublicKeyInfoConverter
{
internal override AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams)
{
KyberParameters parameters = PqcUtilities.KyberParamsLookup(keyInfo.Algorithm.Algorithm);
try {
KyberPublicKey instance = KyberPublicKey.GetInstance(keyInfo.ParsePublicKey());
return new KyberPublicKeyParameters(parameters, instance.T, instance.Rho);
} catch (Exception) {
return new KyberPublicKeyParameters(parameters, keyInfo.PublicKey.GetOctets());
}
}
}
private class FalconConverter : SubjectPublicKeyInfoConverter
{
internal override AsymmetricKeyParameter GetPublicKeyParameters(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 class BikeConverter : SubjectPublicKeyInfoConverter
{
internal override AsymmetricKeyParameter GetPublicKeyParameters(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 class HqcConverter : SubjectPublicKeyInfoConverter
{
internal override AsymmetricKeyParameter GetPublicKeyParameters(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);
}
}
}
private static Dictionary<DerObjectIdentifier, SubjectPublicKeyInfoConverter> Converters;
static PqcPublicKeyFactory()
{
Converters = new Dictionary<DerObjectIdentifier, SubjectPublicKeyInfoConverter>();
Converters[PkcsObjectIdentifiers.IdAlgHssLmsHashsig] = new LmsConverter();
Converters[BCObjectIdentifiers.mceliece348864_r3] = new CmceConverter();
Converters[BCObjectIdentifiers.mceliece348864f_r3] = new CmceConverter();
Converters[BCObjectIdentifiers.mceliece460896_r3] = new CmceConverter();
Converters[BCObjectIdentifiers.mceliece460896f_r3] = new CmceConverter();
Converters[BCObjectIdentifiers.mceliece6688128_r3] = new CmceConverter();
Converters[BCObjectIdentifiers.mceliece6688128f_r3] = new CmceConverter();
Converters[BCObjectIdentifiers.mceliece6960119_r3] = new CmceConverter();
Converters[BCObjectIdentifiers.mceliece6960119f_r3] = new CmceConverter();
Converters[BCObjectIdentifiers.mceliece8192128_r3] = new CmceConverter();
Converters[BCObjectIdentifiers.mceliece8192128f_r3] = new CmceConverter();
Converters[BCObjectIdentifiers.frodokem640aes] = new FrodoConverter();
Converters[BCObjectIdentifiers.frodokem640shake] = new FrodoConverter();
Converters[BCObjectIdentifiers.frodokem976aes] = new FrodoConverter();
Converters[BCObjectIdentifiers.frodokem976shake] = new FrodoConverter();
Converters[BCObjectIdentifiers.frodokem1344aes] = new FrodoConverter();
Converters[BCObjectIdentifiers.frodokem1344shake] = new FrodoConverter();
Converters[BCObjectIdentifiers.lightsaberkem128r3] = new SaberConverter();
Converters[BCObjectIdentifiers.saberkem128r3] = new SaberConverter();
Converters[BCObjectIdentifiers.firesaberkem128r3] = new SaberConverter();
Converters[BCObjectIdentifiers.lightsaberkem192r3] = new SaberConverter();
Converters[BCObjectIdentifiers.saberkem192r3] = new SaberConverter();
Converters[BCObjectIdentifiers.firesaberkem192r3] = new SaberConverter();
Converters[BCObjectIdentifiers.lightsaberkem256r3] = new SaberConverter();
Converters[BCObjectIdentifiers.saberkem256r3] = new SaberConverter();
Converters[BCObjectIdentifiers.firesaberkem256r3] = new SaberConverter();
Converters[BCObjectIdentifiers.ulightsaberkemr3] = new SaberConverter();
Converters[BCObjectIdentifiers.usaberkemr3] = new SaberConverter();
Converters[BCObjectIdentifiers.ufiresaberkemr3] = new SaberConverter();
Converters[BCObjectIdentifiers.lightsaberkem90sr3] = new SaberConverter();
Converters[BCObjectIdentifiers.saberkem90sr3] = new SaberConverter();
Converters[BCObjectIdentifiers.firesaberkem90sr3] = new SaberConverter();
Converters[BCObjectIdentifiers.ulightsaberkem90sr3] = new SaberConverter();
Converters[BCObjectIdentifiers.usaberkem90sr3] = new SaberConverter();
Converters[BCObjectIdentifiers.ufiresaberkem90sr3] = new SaberConverter();
Converters[BCObjectIdentifiers.picnic] = new PicnicConverter();
Converters[BCObjectIdentifiers.picnicl1fs] = new PicnicConverter();
Converters[BCObjectIdentifiers.picnicl1ur] = new PicnicConverter();
Converters[BCObjectIdentifiers.picnicl3fs] = new PicnicConverter();
Converters[BCObjectIdentifiers.picnicl3ur] = new PicnicConverter();
Converters[BCObjectIdentifiers.picnicl5fs] = new PicnicConverter();
Converters[BCObjectIdentifiers.picnicl5ur] = new PicnicConverter();
Converters[BCObjectIdentifiers.picnic3l1] = new PicnicConverter();
Converters[BCObjectIdentifiers.picnic3l3] = new PicnicConverter();
Converters[BCObjectIdentifiers.picnic3l5] = new PicnicConverter();
Converters[BCObjectIdentifiers.picnicl1full] = new PicnicConverter();
Converters[BCObjectIdentifiers.picnicl3full] = new PicnicConverter();
Converters[BCObjectIdentifiers.picnicl5full] = new PicnicConverter();
Converters[BCObjectIdentifiers.sikep434] = new SikeConverter();
Converters[BCObjectIdentifiers.sikep503] = new SikeConverter();
Converters[BCObjectIdentifiers.sikep610] = new SikeConverter();
Converters[BCObjectIdentifiers.sikep751] = new SikeConverter();
Converters[BCObjectIdentifiers.sikep434_compressed] = new SikeConverter();
Converters[BCObjectIdentifiers.sikep503_compressed] = new SikeConverter();
Converters[BCObjectIdentifiers.sikep610_compressed] = new SikeConverter();
Converters[BCObjectIdentifiers.sikep751_compressed] = new SikeConverter();
Converters[BCObjectIdentifiers.dilithium2] = new DilithiumConverter();
Converters[BCObjectIdentifiers.dilithium3] = new DilithiumConverter();
Converters[BCObjectIdentifiers.dilithium5] = new DilithiumConverter();
Converters[BCObjectIdentifiers.dilithium2_aes] = new DilithiumConverter();
Converters[BCObjectIdentifiers.dilithium3_aes] = new DilithiumConverter();
Converters[BCObjectIdentifiers.dilithium5_aes] = new DilithiumConverter();
Converters[BCObjectIdentifiers.falcon_512] = new FalconConverter();
Converters[BCObjectIdentifiers.falcon_1024] = new FalconConverter();
Converters[BCObjectIdentifiers.kyber512] = new KyberConverter();
Converters[BCObjectIdentifiers.kyber512_aes] = new KyberConverter();
Converters[BCObjectIdentifiers.kyber768] = new KyberConverter();
Converters[BCObjectIdentifiers.kyber768_aes] = new KyberConverter();
Converters[BCObjectIdentifiers.kyber1024] = new KyberConverter();
Converters[BCObjectIdentifiers.kyber1024_aes] = new KyberConverter();
Converters[BCObjectIdentifiers.bike128] = new BikeConverter();
Converters[BCObjectIdentifiers.bike192] = new BikeConverter();
Converters[BCObjectIdentifiers.bike256] = new BikeConverter();
Converters[BCObjectIdentifiers.hqc128] = new HqcConverter();
Converters[BCObjectIdentifiers.hqc192] = new HqcConverter();
Converters[BCObjectIdentifiers.hqc256] = new HqcConverter();
Converters[BCObjectIdentifiers.sphincsPlus] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_sha2_128s_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_sha2_128f_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_shake_128s_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_shake_128f_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_haraka_128s_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_haraka_128f_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_sha2_192s_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_sha2_192f_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_shake_192s_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_shake_192f_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_haraka_192s_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_haraka_192f_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_sha2_256s_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_sha2_256f_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_shake_256s_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_shake_256f_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_haraka_256s_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_haraka_256f_r3] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_sha2_128s] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_sha2_128f] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_shake_128s] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_shake_128f] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_sha2_192s] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_sha2_192f] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_shake_192s] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_shake_192f] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_sha2_256s] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_sha2_256f] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_shake_256s] = new SphincsPlusConverter();
Converters[BCObjectIdentifiers.sphincsPlus_shake_256f] = new SphincsPlusConverter();
}
public static AsymmetricKeyParameter CreateKey(byte[] keyInfoData)
{
return CreateKey(SubjectPublicKeyInfo.GetInstance(Asn1Object.FromByteArray(keyInfoData)));
}
public static AsymmetricKeyParameter CreateKey(Stream inStr)
{
return CreateKey(SubjectPublicKeyInfo.GetInstance(new Asn1InputStream(inStr).ReadObject()));
}
public static AsymmetricKeyParameter CreateKey(SubjectPublicKeyInfo keyInfo)
{
return CreateKey(keyInfo, null);
}
public static AsymmetricKeyParameter CreateKey(SubjectPublicKeyInfo keyInfo, object defaultParams)
{
DerObjectIdentifier algorithm = keyInfo.Algorithm.Algorithm;
SubjectPublicKeyInfoConverter valueOrNull = CollectionUtilities.GetValueOrNull(Converters, algorithm);
if (valueOrNull == null)
throw new IOException("algorithm identifier in public key not recognised: " + algorithm?.ToString());
return valueOrNull.GetPublicKeyParameters(keyInfo, defaultParams);
}
}
}