summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Hook <david.hook@keyfactor.com>2022-11-08 12:03:20 +1100
committerDavid Hook <david.hook@keyfactor.com>2022-11-08 12:03:20 +1100
commitca0885f6900a239067f317e6605059db3ebd892f (patch)
tree8743088c2302b40fb6a71873c8555536ecd60ba2
parentMerge remote-tracking branch 'refs/remotes/origin/master' (diff)
downloadBouncyCastle.NET-ed25519-ca0885f6900a239067f317e6605059db3ebd892f.tar.xz
added raw encoding for Dilithium keys
-rw-r--r--crypto/src/pqc/crypto/utils/PublicKeyFactory.cs56
-rw-r--r--crypto/src/pqc/crypto/utils/SubjectPublicKeyInfoFactory.cs3
-rw-r--r--crypto/test/src/pqc/crypto/test/CrystalsDilithiumTest.cs55
3 files changed, 94 insertions, 20 deletions
diff --git a/crypto/src/pqc/crypto/utils/PublicKeyFactory.cs b/crypto/src/pqc/crypto/utils/PublicKeyFactory.cs
index 9eea279b1..792dc6f40 100644
--- a/crypto/src/pqc/crypto/utils/PublicKeyFactory.cs
+++ b/crypto/src/pqc/crypto/utils/PublicKeyFactory.cs
@@ -266,20 +266,28 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
             {
                 DilithiumParameters dilithiumParams = PqcUtilities.DilithiumParamsLookup(keyInfo.AlgorithmID.Algorithm);
 
-                Asn1Object obj = keyInfo.ParsePublicKey();
-                if (obj is Asn1Sequence)
+                try
                 {
-                    Asn1Sequence keySeq = Asn1Sequence.GetInstance(obj);
+                    Asn1Object obj = keyInfo.ParsePublicKey();
+                    if (obj is Asn1Sequence)
+                    {
+                        Asn1Sequence keySeq = Asn1Sequence.GetInstance(obj);
 
-                    return new DilithiumPublicKeyParameters(dilithiumParams,
-                        Asn1OctetString.GetInstance(keySeq[0]).GetOctets(),
-                        Asn1OctetString.GetInstance(keySeq[1]).GetOctets());
+                        return new DilithiumPublicKeyParameters(dilithiumParams,
+                            Asn1OctetString.GetInstance(keySeq[0]).GetOctets(),
+                            Asn1OctetString.GetInstance(keySeq[1]).GetOctets());
+                    }
+                    else
+                    {
+                        byte[] encKey = Asn1OctetString.GetInstance(obj).GetOctets();
+
+                        return new DilithiumPublicKeyParameters(dilithiumParams, encKey);
+                    }
                 }
-                else
+                catch (Exception e)
                 {
-                    byte[] encKey = Asn1OctetString.GetInstance(obj).GetOctets();
-
-                    return new DilithiumPublicKeyParameters(dilithiumParams, encKey);
+                    // raw encoding
+                    return new DilithiumPublicKeyParameters(dilithiumParams, keyInfo.PublicKeyData.GetOctets());
                 }
             }
         }
@@ -316,17 +324,31 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
             {
                 FalconParameters falconParams = PqcUtilities.FalconParamsLookup(keyInfo.AlgorithmID.Algorithm);
 
-                Asn1Object obj = keyInfo.ParsePublicKey();
-                if (obj is Asn1Sequence)
+                try
                 {
-                    byte[] keyEnc = Asn1OctetString.GetInstance(Asn1Sequence.GetInstance(obj)[0]).GetOctets();
+                    Asn1Object obj = keyInfo.ParsePublicKey();
+                    if (obj is Asn1Sequence)
+                    {
+                        byte[] keyEnc = Asn1OctetString.GetInstance(Asn1Sequence.GetInstance(obj)[0]).GetOctets();
 
-                    return new FalconPublicKeyParameters(falconParams, keyEnc);
+                        return new FalconPublicKeyParameters(falconParams, keyEnc);
+                    }
+                    else
+                    {
+                        // header byte + h
+                        byte[] keyEnc = Asn1OctetString.GetInstance(obj).GetOctets();
+
+                        if (keyEnc[0] != (byte)(0x00 + falconParams.LogN))
+                        {
+                            throw new ArgumentException("byte[] enc of Falcon h value not tagged correctly");
+                        }
+                        return new FalconPublicKeyParameters(falconParams, Arrays.CopyOfRange(keyEnc, 1, keyEnc.Length));
+                    }
                 }
-                else
+                catch (Exception e)
                 {
-                    // header byte + h
-                    byte[] keyEnc = Asn1OctetString.GetInstance(obj).GetOctets();
+                    // raw encoding
+                    byte[] keyEnc = keyInfo.PublicKeyData.GetOctets();
 
                     if (keyEnc[0] != (byte)(0x00 + falconParams.LogN))
                     {
diff --git a/crypto/src/pqc/crypto/utils/SubjectPublicKeyInfoFactory.cs b/crypto/src/pqc/crypto/utils/SubjectPublicKeyInfoFactory.cs
index f532cfdae..2b16cb260 100644
--- a/crypto/src/pqc/crypto/utils/SubjectPublicKeyInfoFactory.cs
+++ b/crypto/src/pqc/crypto/utils/SubjectPublicKeyInfoFactory.cs
@@ -125,8 +125,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
                 AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(
                     PqcUtilities.DilithiumOidLookup(dilithiumPublicKeyParameters.Parameters));
             
-                return new SubjectPublicKeyInfo(algorithmIdentifier,
-                    new DerOctetString(Arrays.Concatenate(dilithiumPublicKeyParameters.Rho, dilithiumPublicKeyParameters.T1)));
+                return new SubjectPublicKeyInfo(algorithmIdentifier, Arrays.Concatenate(dilithiumPublicKeyParameters.Rho, dilithiumPublicKeyParameters.T1));
             }
             if (publicKey is BikePublicKeyParameters bikePublicKeyParameters)
             { 
diff --git a/crypto/test/src/pqc/crypto/test/CrystalsDilithiumTest.cs b/crypto/test/src/pqc/crypto/test/CrystalsDilithiumTest.cs
index e1121a5e3..2b74c44d4 100644
--- a/crypto/test/src/pqc/crypto/test/CrystalsDilithiumTest.cs
+++ b/crypto/test/src/pqc/crypto/test/CrystalsDilithiumTest.cs
@@ -1,8 +1,9 @@
+using System;
 using System.Collections.Generic;
 using System.IO;
 
 using NUnit.Framework;
-
+using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium;
 using Org.BouncyCastle.Pqc.Crypto.Utilities;
@@ -53,6 +54,58 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests
             RunTestVectorFile(testVectorFile);
         }
 
+        [Test]
+        public void TestKeyEncodingDilithium2()
+        {
+            byte[] altEncKey = Base64.Decode("oED4ZvqhK4kChPclP5VhOPvvnwof3QeTFq/zR5UtSr6SYicBkpe1TkafnSk5whDHgEp8imVwfeP2LbSopHb5KQuUFstGqsdII9o8Zf+50yempJ1+C5G64KfQlqkI8/Y6cShWWNgeWm/5OGyxhF0hYVGIwaTTs6AN3QaPjSutLPNdZ82Vd4BSNB5dzZMaoYV619rNO7HGlfwrWkyCoDVQftpgw4NjiAnJ0BPcDJTzPVD3cq3Dw5f14AwNsUijLZ4CuRzzCBBx0B+SbIruEnGbDNhfzp3FdDg2sy/hRqD6/0gzOBExzLT8ofBE6D9VcmiPT+KgLbiObhZt+mjzGGE3wnXgmklX5Qr/d7kyamm4tq3xiKm58/VdkB3ASt+ULo1jXQtuoXVkn7vfT/1LAVbJ6QIqvxcQknDj2j2oUSWYLz48qfgNWtbM/EOZ8WBaV9UxO7Sd5wF+/wiVUxrMC+3BdrJnWSP00s7AJBH4NdQfU7E6uK1BhJEDLZaiRshi1lnu7PfKLdKSIyRL73VsmjQhONXtyBy1gG876DSa846d3ppx+kd2FxR5QRtUT5Y3E1lgxYlyInjmRzFoEc6TXyhYFYptvyFKV7FUxClYCLYbE4YPBnbJ3WyaqtmJNCueMlNYGSYR/7yLOjdj8O2j21q+fVI1z9cxOx4A2xHMNiX+mvVaQQLOIQbsbCeKkR6HhnAgblU8ge7n6EFN6hN+24R7FCaCKCQy3HTngw+FBJJYMlcAIvno3KQj25g8nR9uQQ57DNla2yLgGC02cG0ECemIP3nroqohcENydsuaKkzVtDenGakcpERACf4RXqbcvwuSEEH1IU5SjUGTEJgd8/BI/Mgicc5DEyZM18ONrhSpH8oTVuxJ7DAm1MQtmqkHEB71UWAEfPrmcJXz/p+ih5q4nl8k6X/48Du2SEC6YeMMrXUR8JzP3kEVULLaBxXJMtIumnsecAndoxAGdhxY+rJCPPSimc+navloDZ3xO9+nqimeOuvnKAZGxr7aiWt+h4xL+H1ZkO/NlMdWhbIeyohJhtZ2pav8XDZLAbJmNNGJH8/4RjG3TsA5rEoqiulnTgtWNj7POiITmPrHoG+d88AB5JalRZm1Mm6nSdKH96U2dN0rZWgP+qc6xl8/Rn6jMnOY9dPTpVq9IrTAiqeBIj5vpAn0Y4oXuCEn3hjFeDxvcSqbAFAE8Tf+GABHQRVBapw0tL3JW4GKT92BlKmDzqVu7XQIuTJ4wPu1WQ95DbGzIGrh45x0UbU1h9S1xWcJLCy1RnoImocvvI3T0JpChuZvSmThNauV3dhoOojh522X38uxuXfgl7ziQmUIPR/YI9CUIm7mKB9el8HlgSa35HZaWWRGuik6ceEN9s0ZkWNOlREth+FDD7JoKiZh8ehgfK/1sQM/2c/8fsyysGeFrmSAkp9jwGKIvd+feJneoUgxZg2mzMmVjZM4J6vjseOUypzKeb1zRzNCw6UAF6LJNDcBzmlYk0gjMibofI/UaWaPEnXyiaFEFfWlYPFvDcd/ehPm7ft9tpLYnbx6ETW8FMHvnbrXTdNeZlU9UWO5NpSW+WbGTKcbU8ZJBECN49HYBiv0OBHWjGYj8hb/1ig05m4/uyr6zOG8So87CDR8FfZMk+3YOf2hmb5LzdRskcMABDOdNeKz8Bnc0uIuc8MqtGWtGgPiDpnj8R123MO30BpYugpQhLZm5wjX+i4ZMkj2DrBY1TAlo1JSR0LTnspR4IA4eQ==");
+            byte[] altSubPubEnc = Base64.Decode("MIIFODANBgsrBgEEAQKCCwcEBAOCBSUABIIFIKBA+Gb6oSuJAoT3JT+VYTj7758KH90Hkxav80eVLUq+kmInAZKXtU5Gn50pOcIQx4BKfIplcH3j9i20qKR2+SkLlBbLRqrHSCPaPGX/udMnpqSdfguRuuCn0JapCPP2OnEoVljYHlpv+ThssYRdIWFRiMGk07OgDd0Gj40rrSzzXWfNlXeAUjQeXc2TGqGFetfazTuxxpX8K1pMgqA1UH7aYMODY4gJydAT3AyU8z1Q93Ktw8OX9eAMDbFIoy2eArkc8wgQcdAfkmyK7hJxmwzYX86dxXQ4NrMv4Uag+v9IMzgRMcy0/KHwROg/VXJoj0/ioC24jm4Wbfpo8xhhN8J14JpJV+UK/3e5MmppuLat8YipufP1XZAdwErflC6NY10LbqF1ZJ+730/9SwFWyekCKr8XEJJw49o9qFElmC8+PKn4DVrWzPxDmfFgWlfVMTu0necBfv8IlVMazAvtwXayZ1kj9NLOwCQR+DXUH1OxOritQYSRAy2WokbIYtZZ7uz3yi3SkiMkS+91bJo0ITjV7cgctYBvO+g0mvOOnd6acfpHdhcUeUEbVE+WNxNZYMWJciJ45kcxaBHOk18oWBWKbb8hSlexVMQpWAi2GxOGDwZ2yd1smqrZiTQrnjJTWBkmEf+8izo3Y/Dto9tavn1SNc/XMTseANsRzDYl/pr1WkECziEG7GwnipEeh4ZwIG5VPIHu5+hBTeoTftuEexQmgigkMtx054MPhQSSWDJXACL56NykI9uYPJ0fbkEOewzZWtsi4BgtNnBtBAnpiD9566KqIXBDcnbLmipM1bQ3pxmpHKREQAn+EV6m3L8LkhBB9SFOUo1BkxCYHfPwSPzIInHOQxMmTNfDja4UqR/KE1bsSewwJtTELZqpBxAe9VFgBHz65nCV8/6fooeauJ5fJOl/+PA7tkhAumHjDK11EfCcz95BFVCy2gcVyTLSLpp7HnAJ3aMQBnYcWPqyQjz0opnPp2r5aA2d8Tvfp6opnjrr5ygGRsa+2olrfoeMS/h9WZDvzZTHVoWyHsqISYbWdqWr/Fw2SwGyZjTRiR/P+EYxt07AOaxKKorpZ04LVjY+zzoiE5j6x6BvnfPAAeSWpUWZtTJup0nSh/elNnTdK2VoD/qnOsZfP0Z+ozJzmPXT06VavSK0wIqngSI+b6QJ9GOKF7ghJ94YxXg8b3EqmwBQBPE3/hgAR0EVQWqcNLS9yVuBik/dgZSpg86lbu10CLkyeMD7tVkPeQ2xsyBq4eOcdFG1NYfUtcVnCSwstUZ6CJqHL7yN09CaQobmb0pk4TWrld3YaDqI4edtl9/Lsbl34Je84kJlCD0f2CPQlCJu5igfXpfB5YEmt+R2WllkRropOnHhDfbNGZFjTpURLYfhQw+yaComYfHoYHyv9bEDP9nP/H7MsrBnha5kgJKfY8BiiL3fn3iZ3qFIMWYNpszJlY2TOCer47HjlMqcynm9c0czQsOlABeiyTQ3Ac5pWJNIIzIm6HyP1GlmjxJ18omhRBX1pWDxbw3Hf3oT5u37fbaS2J28ehE1vBTB7526103TXmZVPVFjuTaUlvlmxkynG1PGSQRAjePR2AYr9DgR1oxmI/IW/9YoNOZuP7sq+szhvEqPOwg0fBX2TJPt2Dn9oZm+S83UbJHDAAQznTXis/AZ3NLiLnPDKrRlrRoD4g6Z4/EddtzDt9AaWLoKUIS2ZucI1/ouGTJI9g6wWNUwJaNSUkdC057KUeCAOHk=");
+
+            AsymmetricKeyParameter altPubDec = PublicKeyFactory.CreateKey(SubjectPublicKeyInfo.GetInstance(altSubPubEnc));
+            Assert.AreEqual(altEncKey, ((DilithiumPublicKeyParameters)altPubDec).GetEncoded());
+    
+            Security.SecureRandom random = new Security.SecureRandom();
+            DilithiumKeyGenerationParameters kparam = new DilithiumKeyGenerationParameters(random, DilithiumParameters.Dilithium2);
+            DilithiumKeyPairGenerator kpg = new DilithiumKeyPairGenerator();
+            kpg.Init(kparam);
+            AsymmetricCipherKeyPair ackp = kpg.GenerateKeyPair();
+
+            AsymmetricKeyParameter pub = ackp.Public;
+            AsymmetricKeyParameter priv = ackp.Private;
+
+            AsymmetricKeyParameter pubDec = PublicKeyFactory.CreateKey(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub));
+            AsymmetricKeyParameter privDec = PrivateKeyFactory.CreateKey(PrivateKeyInfoFactory.CreatePrivateKeyInfo(priv));
+
+            Console.Out.WriteLine(Base64.ToBase64String(((DilithiumPublicKeyParameters)pub).GetEncoded()));
+            Console.Out.WriteLine(Base64.ToBase64String(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub).GetEncoded()));
+            Assert.AreEqual(((DilithiumPublicKeyParameters)pub).GetEncoded(), ((DilithiumPublicKeyParameters)pubDec).GetEncoded());
+            Assert.AreEqual(((DilithiumPrivateKeyParameters)priv).GetEncoded(), ((DilithiumPrivateKeyParameters)privDec).GetEncoded());
+        }
+
+        [Test]
+        public void TestKeyEncodingDilithium2Aes()
+        {
+            byte[] altEncKey = Base64.Decode("CKJBWPvTOpeLU/2y0fhlWLc9HKYgH2pAARm2IzwF927Nnnugbw4T7cmjtSfbD/e4CamjVdehDBPqYBWfbZumLD+EuPQUqWaCYDS9JcezFmFXACFHRQPwWDqwqvfuy7zeN4HVb/ygiNJI/mWNoqRn3Ffz59J2iPLr9xe8TUNgQ6VK3tVwIqkxAXv1GVX5MCJI0U2v7d00RnfEDnYL2AVZjSGe0fboKN74OrMTLlx2qN9a8uw21mcgvULBIItsppN7w+gSjOnqSg22wA2RojBNZRuQm4AVeZR6mPw0cYVSyBD3DSjPCWhwseJOACfxdaKgPUQOYlYvQLTTQ1O8fYsrmdF/8aisZ9oo7HVz5xC46AEIL2mp5eVGZJxFpvYyUet0JMFmDgv1PUtoja/EfORNM2T1+pHkv6InfyIDXS3+SMuH0S4qUCmhNtKV47L5uVUl0dfgzDdvsooEZ8iCT1z3nAWiaDNKbMEdYvY7/Qm2HtJIMzLyyXfD9kkwAGr/rzU4IyqK0cS97cVeeT86Zt0e4OtLXJnjhNpD4v+qukjnRVeov/tGzDUtohcAghTTArx3/E3ZEOrDzgagyHKu/3IefhVqndYMle8+NuYIjbN0J/CFOgIpL81ZgVgdCDrj0MWGhPwlUeQcDRnMqxrEtCeXO+X7v2A2USd7Nss0aQOdfN1VzBNV18IWQEeD37pQPyEsyWkLYr6WNyIEZ7gqOpHc4eyWCccI6n3f0Q2kN7YqcX3Gxgbxa8i9P81HxFHfEwabcsXZXmCUowqfGVfx+np2wyYP0uOQrER29vq99RyV1NgXkjtKW1scaVWUFHsaT4nluJjHQ46V77R7HvNZUcvLmKtqtqGAJoe74Aiy5Ft2PnNBNSFs9XQOpuNnZsoTLm29ZGI5FnXf59U7Qm4j9gYB1ra2KzWkzcbjyaPk2aPCPTZHcsp8cyp5V6n9jux5PoW1iJmxo40Rso3fS04bhgZxRbQzcEIPG2iwdpa5qiFD17AC8o6LSWjhxoNgRwHqC7vCdWJyLsCdvN6kkKjdG0DFJpylr/fiBgBj8pm/XdTSboIdrcKvmITcRHXlC02XzdzIehFGeDrDDn0/mCzMHqGnYIhbY1wMywP8BMzesv/igbTEhk/tKVa3//CaVCESO0Ma4HVVSxuuNvlgGSf7Af0n5fcqA/zSJe9iKEj0PPEr1VMbatzbTqBH7jQqQEgOEsG/E2vCtOJU343f1pPntdWwnj6k05s+IroRReGM9ZEDCw+r/QMGOQEbMljirwtM/2wkA/yzZcp1UqzLTQnY38jcJWpD+z0ld9wPFRf0EzJF6HE5ShljNS76qBvlcIJdem8mIO4wtDBY6cNMRc4TFcETz4qC0ws7bzXN47z7Cq6VtutOph+R0deGMvS1T6Ryn7MzmMefduDHvsUWPiBeD4siCPqxgy5Q2Bw5lxlAS7JQ8tuxkSISRs6wJCv8morF4CM2Z4IpQ6VWnFm4d+PyYIxPmHZ9d4HIOPUh7mzMJ2OG6ouOdK9a7W5cBCt23KMJMyiU1YqEGxRr4vyzlqCHfuqGTtke7kHUivMMtTHJnz1pd1r7pGn8AL8XcQNkoSt6u4GrNXMiA4Sj3ZFvIZeO7YjZ6RKv8CpRPYkE7qt0To5ZK3+Jt1cVGRG/9/tcBLCrBWwWQGCc0GaKhktI50hjDXZly+i2UW00p+LYEx7qWPZljYOoD+ued6Rog+HZ0Eit6/NZCAtK2quf/aDn0XaxoEfpuA==");
+            byte[] altSubPubEnc = Base64.Decode("MIIFODANBgsrBgEEAQKCCwsEBAOCBSUABIIFIAiiQVj70zqXi1P9stH4ZVi3PRymIB9qQAEZtiM8BfduzZ57oG8OE+3Jo7Un2w/3uAmpo1XXoQwT6mAVn22bpiw/hLj0FKlmgmA0vSXHsxZhVwAhR0UD8Fg6sKr37su83jeB1W/8oIjSSP5ljaKkZ9xX8+fSdojy6/cXvE1DYEOlSt7VcCKpMQF79RlV+TAiSNFNr+3dNEZ3xA52C9gFWY0hntH26Cje+DqzEy5cdqjfWvLsNtZnIL1CwSCLbKaTe8PoEozp6koNtsANkaIwTWUbkJuAFXmUepj8NHGFUsgQ9w0ozwlocLHiTgAn8XWioD1EDmJWL0C000NTvH2LK5nRf/GorGfaKOx1c+cQuOgBCC9pqeXlRmScRab2MlHrdCTBZg4L9T1LaI2vxHzkTTNk9fqR5L+iJ38iA10t/kjLh9EuKlApoTbSleOy+blVJdHX4Mw3b7KKBGfIgk9c95wFomgzSmzBHWL2O/0Jth7SSDMy8sl3w/ZJMABq/681OCMqitHEve3FXnk/OmbdHuDrS1yZ44TaQ+L/qrpI50VXqL/7Rsw1LaIXAIIU0wK8d/xN2RDqw84GoMhyrv9yHn4Vap3WDJXvPjbmCI2zdCfwhToCKS/NWYFYHQg649DFhoT8JVHkHA0ZzKsaxLQnlzvl+79gNlEnezbLNGkDnXzdVcwTVdfCFkBHg9+6UD8hLMlpC2K+ljciBGe4KjqR3OHslgnHCOp939ENpDe2KnF9xsYG8WvIvT/NR8RR3xMGm3LF2V5glKMKnxlX8fp6dsMmD9LjkKxEdvb6vfUcldTYF5I7SltbHGlVlBR7Gk+J5biYx0OOle+0ex7zWVHLy5irarahgCaHu+AIsuRbdj5zQTUhbPV0DqbjZ2bKEy5tvWRiORZ13+fVO0JuI/YGAda2tis1pM3G48mj5Nmjwj02R3LKfHMqeVep/Y7seT6FtYiZsaONEbKN30tOG4YGcUW0M3BCDxtosHaWuaohQ9ewAvKOi0lo4caDYEcB6gu7wnVici7AnbzepJCo3RtAxSacpa/34gYAY/KZv13U0m6CHa3Cr5iE3ER15QtNl83cyHoRRng6ww59P5gszB6hp2CIW2NcDMsD/ATM3rL/4oG0xIZP7SlWt//wmlQhEjtDGuB1VUsbrjb5YBkn+wH9J+X3KgP80iXvYihI9DzxK9VTG2rc206gR+40KkBIDhLBvxNrwrTiVN+N39aT57XVsJ4+pNObPiK6EUXhjPWRAwsPq/0DBjkBGzJY4q8LTP9sJAP8s2XKdVKsy00J2N/I3CVqQ/s9JXfcDxUX9BMyRehxOUoZYzUu+qgb5XCCXXpvJiDuMLQwWOnDTEXOExXBE8+KgtMLO281zeO8+wqulbbrTqYfkdHXhjL0tU+kcp+zM5jHn3bgx77FFj4gXg+LIgj6sYMuUNgcOZcZQEuyUPLbsZEiEkbOsCQr/JqKxeAjNmeCKUOlVpxZuHfj8mCMT5h2fXeByDj1Ie5szCdjhuqLjnSvWu1uXAQrdtyjCTMolNWKhBsUa+L8s5agh37qhk7ZHu5B1IrzDLUxyZ89aXda+6Rp/AC/F3EDZKEreruBqzVzIgOEo92RbyGXju2I2ekSr/AqUT2JBO6rdE6OWSt/ibdXFRkRv/f7XASwqwVsFkBgnNBmioZLSOdIYw12ZcvotlFtNKfi2BMe6lj2ZY2DqA/rnnekaIPh2dBIrevzWQgLStqrn/2g59F2saBH6bg=");
+           
+            AsymmetricKeyParameter altPubDec = PublicKeyFactory.CreateKey(SubjectPublicKeyInfo.GetInstance(altSubPubEnc));
+            Assert.AreEqual(altEncKey, ((DilithiumPublicKeyParameters)altPubDec).GetEncoded());
+
+            Security.SecureRandom random = new Security.SecureRandom();
+            DilithiumKeyGenerationParameters kparam = new DilithiumKeyGenerationParameters(random, DilithiumParameters.Dilithium2Aes);
+            DilithiumKeyPairGenerator kpg = new DilithiumKeyPairGenerator();
+            kpg.Init(kparam);
+            AsymmetricCipherKeyPair ackp = kpg.GenerateKeyPair();
+
+            AsymmetricKeyParameter pub = ackp.Public;
+            AsymmetricKeyParameter priv = ackp.Private;
+
+            AsymmetricKeyParameter pubDec = PublicKeyFactory.CreateKey(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub));
+            AsymmetricKeyParameter privDec = PrivateKeyFactory.CreateKey(PrivateKeyInfoFactory.CreatePrivateKeyInfo(priv));
+
+            Assert.AreEqual(((DilithiumPublicKeyParameters)pub).GetEncoded(), ((DilithiumPublicKeyParameters)pubDec).GetEncoded());
+            Assert.AreEqual(((DilithiumPrivateKeyParameters)priv).GetEncoded(), ((DilithiumPrivateKeyParameters)privDec).GetEncoded());
+        }
+
         private static void RunTestVector(string name, IDictionary<string, string> buf)
         {
             string count = buf["count"];