From f1521d0d933f570711612efd845b41906917636d Mon Sep 17 00:00:00 2001 From: Bence Mali Date: Thu, 29 Aug 2024 17:54:42 +0200 Subject: [PATCH 01/10] hybrid key support WIP --- .../crypto/generators/HybridKemGenerator.cs | 197 +++++++++++++ .../generators/HybridSignatureGenerator.cs | 87 ++++++ .../HybridKeyGenerationParameters.cs | 269 ++++++++++++++++++ .../crypto/parameters/HybridKeyParameters.cs | 238 ++++++++++++++++ crypto/src/pkcs/PrivateKeyInfoFactory.cs | 6 + crypto/src/security/PrivateKeyFactory.cs | 5 + crypto/src/security/PublicKeyFactory.cs | 5 + .../src/x509/SubjectPublicKeyInfoFactory.cs | 6 + 8 files changed, 813 insertions(+) create mode 100644 crypto/src/crypto/generators/HybridKemGenerator.cs create mode 100644 crypto/src/crypto/generators/HybridSignatureGenerator.cs create mode 100644 crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs create mode 100644 crypto/src/crypto/parameters/HybridKeyParameters.cs diff --git a/crypto/src/crypto/generators/HybridKemGenerator.cs b/crypto/src/crypto/generators/HybridKemGenerator.cs new file mode 100644 index 000000000..8a9d70b30 --- /dev/null +++ b/crypto/src/crypto/generators/HybridKemGenerator.cs @@ -0,0 +1,197 @@ +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.crypto.parameters; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; +using Org.BouncyCastle.Pqc.Crypto.Utilities; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace Org.BouncyCastle.crypto.generators +{ + public class HybridKemGenerator + : IAsymmetricCipherKeyPairGenerator + { + private HybridKeyGenerationParameters parameters; + + private SecureRandom random; + + public void Init(KeyGenerationParameters parameters) + { + if (!(parameters is HybridKeyGenerationParameters)) + { + throw new ArgumentException("Provided parameter is not hybrid parameter"); + } + + this.parameters = parameters as HybridKeyGenerationParameters; + this.random = parameters.Random; + } + + public AsymmetricCipherKeyPair GenerateKeyPair() + { + AsymmetricCipherKeyPair classicalKeypair = null; + if (parameters.ClassicalParameters is ECKeyGenerationParameters) + { + var generator = new ECKeyPairGenerator("ECDH"); + generator.Init(parameters.ClassicalParameters); + classicalKeypair = generator.GenerateKeyPair(); + } + else if (parameters.ClassicalParameters is RsaKeyGenerationParameters) + { + // TODO + throw new NotImplementedException("Rsa hybrid keypair generation not supported"); + } + + if (classicalKeypair == null) + { + throw new Exception("Classical parameter not supported"); + } + + AsymmetricCipherKeyPair postQuantumKeypair = null; + if (parameters.PostQuantumParameters is KyberKeyGenerationParameters) + { + var generator = new KyberKeyPairGenerator(); + generator.Init(parameters.PostQuantumParameters); + postQuantumKeypair = generator.GenerateKeyPair(); + } + + if (postQuantumKeypair == null) + { + throw new Exception("Post-quantum parameter not supported"); + } + + return new AsymmetricCipherKeyPair(new HybridKeyParameters(classicalKeypair.Public, postQuantumKeypair.Public), new HybridKeyParameters(classicalKeypair.Private, postQuantumKeypair.Private)); + } + + public static ISecretWithEncapsulation Encapsulate(AsymmetricKeyParameter pubKey) + { + if (!(pubKey is HybridKeyParameters)) + { + throw new ArgumentException("Provided key parameter is not hybrid"); + } + + var hybridPubKey = pubKey as HybridKeyParameters; + + byte[] classicalCiphertext = null; + byte[] classicalSharedSecret = null; + if (hybridPubKey.Classical is ECPublicKeyParameters) + { + var generator = new ECKeyPairGenerator("ECDH"); + var pubInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(hybridPubKey.Classical); + var parameters = new ECKeyGenerationParameters(pubInfo.Algorithm.Algorithm, new SecureRandom()); + generator.Init(parameters); + var ephemeralKeypair = generator.GenerateKeyPair(); + + classicalCiphertext = (ephemeralKeypair.Public as ECPublicKeyParameters).Q.GetEncoded(); + + var ecdhAgreement = new ECDHBasicAgreement(); + ecdhAgreement.Init(ephemeralKeypair.Private); + classicalSharedSecret = ecdhAgreement.CalculateAgreement(hybridPubKey.Classical).ToByteArrayUnsigned(); + } + else if (hybridPubKey.Classical is RsaKeyParameters) + { + // TODO + throw new NotImplementedException("Rsa hybrid encapsulation not supported"); + } + + if (classicalCiphertext == null || classicalSharedSecret == null) + { + throw new Exception("Classical public key not supported"); + } + + byte[] postQuantumCiphertext = null; + byte[] postQuantumSharedSecret = null; + if (hybridPubKey.PostQuantum is KyberPublicKeyParameters) + { + var encapsulation = new KyberKemGenerator(new SecureRandom()).GenerateEncapsulated(hybridPubKey.PostQuantum); + postQuantumCiphertext = encapsulation.GetEncapsulation(); + postQuantumSharedSecret = encapsulation.GetSecret(); + } + + if (postQuantumCiphertext == null || postQuantumSharedSecret == null) + { + throw new Exception("Post-quantum public key not supported"); + } + + return new SecretWithEncapsulationImpl(Arrays.Concatenate(classicalSharedSecret, postQuantumSharedSecret), Arrays.Concatenate(classicalCiphertext, postQuantumCiphertext)); + } + + public static byte[] Decapsulate(AsymmetricKeyParameter privKey, byte[] ciphertext) + { + if (!(privKey is HybridKeyParameters)) + { + throw new ArgumentException("Provided key parameter is not hybrid"); + } + if (!privKey.IsPrivate) + { + throw new ArgumentException("Provided key is not a private key"); + } + + var hybridPrivKey = privKey as HybridKeyParameters; + + byte[] classicalSharedSecret = null; + if (hybridPrivKey.Classical is ECPrivateKeyParameters) + { + var classical = hybridPrivKey.Classical as ECPrivateKeyParameters; + + // public key is uncompressed ec point + var publicKeySize = (classical.Parameters.Curve.FieldElementEncodingLength * 2) + 1; + + if (ciphertext.Length <= publicKeySize) + { + throw new Exception("Wrong size classical ciphertext"); + } + + var publicKeyBytes = ciphertext.Take(publicKeySize).ToArray(); + var otherPublicKey = new ECPublicKeyParameters(classical.Parameters.Curve.DecodePoint(publicKeyBytes), classical.Parameters); + + var ecdhAgreement = new ECDHBasicAgreement(); + ecdhAgreement.Init(classical); + classicalSharedSecret = ecdhAgreement.CalculateAgreement(otherPublicKey).ToByteArrayUnsigned(); + + // take away classical ciphertext + ciphertext = ciphertext.Skip(publicKeySize).ToArray(); + } + else if (hybridPrivKey.Classical is RsaKeyParameters) + { + // TODO + throw new NotImplementedException("Rsa hybrid decapsulation not supported"); + } + + if (classicalSharedSecret == null) + { + throw new Exception("Classical keytype not supported"); + } + + byte[] postQuantumSharedSecret = null; + if (hybridPrivKey.PostQuantum is KyberPrivateKeyParameters) + { + var extractor = new KyberKemExtractor(hybridPrivKey.PostQuantum as KyberPrivateKeyParameters); + if (ciphertext.Length != extractor.EncapsulationLength) + { + throw new Exception("Wrong size post-quantum ciphertext"); + } + postQuantumSharedSecret = new KyberKemExtractor(hybridPrivKey.PostQuantum as KyberPrivateKeyParameters).ExtractSecret(ciphertext); + } + + if (postQuantumSharedSecret == null) + { + throw new Exception("Post-quantum keytype not supported"); + } + + return Arrays.Concatenate(classicalSharedSecret, postQuantumSharedSecret); + } + } +} diff --git a/crypto/src/crypto/generators/HybridSignatureGenerator.cs b/crypto/src/crypto/generators/HybridSignatureGenerator.cs new file mode 100644 index 000000000..dfc23d008 --- /dev/null +++ b/crypto/src/crypto/generators/HybridSignatureGenerator.cs @@ -0,0 +1,87 @@ +using Org.BouncyCastle.crypto.parameters; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Pqc.Crypto; +using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; +using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; +using Org.BouncyCastle.Security; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Org.BouncyCastle.crypto.generators +{ + public class HybridSignatureGenerator + : IAsymmetricCipherKeyPairGenerator + { + private HybridKeyGenerationParameters parameters; + + private SecureRandom random; + + public void Init(KeyGenerationParameters parameters) + { + if (!(parameters is HybridKeyGenerationParameters)) + { + throw new ArgumentException("Provided parameter is not hybrid parameter"); + } + + this.parameters = parameters as HybridKeyGenerationParameters; + this.random = this.parameters.Random; + } + + public AsymmetricCipherKeyPair GenerateKeyPair() + { + AsymmetricCipherKeyPair classicalKeypair = null; + if (parameters.ClassicalParameters is ECKeyGenerationParameters) + { + var generator = new ECKeyPairGenerator("ECDSA"); + generator.Init(parameters.ClassicalParameters); + classicalKeypair = generator.GenerateKeyPair(); + } + else if (parameters.ClassicalParameters is RsaKeyGenerationParameters) + { + // TODO + throw new NotImplementedException("Rsa hybrid keypair generation not supported"); + } + + if (classicalKeypair == null) + { + throw new Exception("Classical parameter not supported"); + } + + AsymmetricCipherKeyPair postQuantumKeypair = null; + if (parameters.PostQuantumParameters is DilithiumKeyGenerationParameters) + { + var generator = new DilithiumKeyPairGenerator(); + generator.Init(parameters.PostQuantumParameters); + postQuantumKeypair = generator.GenerateKeyPair(); + } + else if (parameters.PostQuantumParameters is SphincsPlusKeyGenerationParameters) + { + var generator = new SphincsPlusKeyPairGenerator(); + generator.Init(parameters.PostQuantumParameters); + postQuantumKeypair = generator.GenerateKeyPair(); + } + + if (postQuantumKeypair == null) + { + throw new Exception("Post-quantum parameter not supported"); + } + + return new AsymmetricCipherKeyPair(new HybridKeyParameters(classicalKeypair.Public, postQuantumKeypair.Public), new HybridKeyParameters(classicalKeypair.Private, postQuantumKeypair.Private)); + } + + public static byte[] GenerateSignature(AsymmetricKeyParameter privKey, byte[] message) + { + // FIXME(bence) + } + + public static bool VerifySignature(AsymmetricKeyParameter pubKey, byte[] message, byte[] signature) + { + // FIXME(bence) + } + } +} diff --git a/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs b/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs new file mode 100644 index 000000000..ab852f1d8 --- /dev/null +++ b/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs @@ -0,0 +1,269 @@ +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.BC; +using Org.BouncyCastle.Asn1.EdEC; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; +using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; +using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; +using Org.BouncyCastle.Security; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Org.BouncyCastle.crypto.parameters +{ + public class HybridKeyGenerationParameters + : KeyGenerationParameters + { + public Dictionary classicalNameToOid = new Dictionary() + { + { "p256", SecObjectIdentifiers.SecP256r1 }, + { "p384", SecObjectIdentifiers.SecP384r1 }, + { "p512", SecObjectIdentifiers.SecP521r1 }, + { "x25519", EdECObjectIdentifiers.id_X25519 }, + { "x448", EdECObjectIdentifiers.id_X448 }, + { "ed25519", EdECObjectIdentifiers.id_Ed25519 }, + { "ed448", EdECObjectIdentifiers.id_Ed448 }, + }; + + public Dictionary classicalOidToName = new Dictionary() + { + { SecObjectIdentifiers.SecP256r1, "p256" }, + { SecObjectIdentifiers.SecP384r1, "p384" }, + { SecObjectIdentifiers.SecP521r1, "p521" }, + { EdECObjectIdentifiers.id_X25519, "x25519" }, + { EdECObjectIdentifiers.id_X448, "x448" }, + { EdECObjectIdentifiers.id_Ed25519, "ed25519" }, + { EdECObjectIdentifiers.id_Ed448, "ed448" }, + }; + + public Dictionary postQuantumNameToOid = new Dictionary() + { + { "kyber512", BCObjectIdentifiers.kyber512 }, + { "kyber768", BCObjectIdentifiers.kyber768 }, + { "kyber1024", BCObjectIdentifiers.kyber1024 }, + { "mlkem512", BCObjectIdentifiers.kyber512 }, + { "mlkem768", BCObjectIdentifiers.kyber768 }, + { "mlkem1024", BCObjectIdentifiers.kyber1024 }, + { "dilithium2", BCObjectIdentifiers.dilithium2 }, + { "dilithium3", BCObjectIdentifiers.dilithium3 }, + { "dilithium5", BCObjectIdentifiers.dilithium5 }, + { "mldsa44", BCObjectIdentifiers.dilithium2 }, + { "mldsa65", BCObjectIdentifiers.dilithium3 }, + { "mldsa87", BCObjectIdentifiers.dilithium5 }, + { "sphincssha2128fsimple", BCObjectIdentifiers.sphincsPlus_sha2_128f }, + { "sphincssha2192fsimple", BCObjectIdentifiers.sphincsPlus_sha2_192f }, + { "sphincssha2256fsimple", BCObjectIdentifiers.sphincsPlus_sha2_256f }, + }; + + public Dictionary postQuantumOidToName = new Dictionary() + { + { BCObjectIdentifiers.kyber512, "kyber512" }, + { BCObjectIdentifiers.kyber768, "kyber768" }, + { BCObjectIdentifiers.kyber1024, "kyber1024" }, + { BCObjectIdentifiers.kyber512, "mlkem512" }, + { BCObjectIdentifiers.kyber768, "mlkem768" }, + { BCObjectIdentifiers.kyber1024, "mlkem1024" }, + { BCObjectIdentifiers.dilithium2, "dilithium2" }, + { BCObjectIdentifiers.dilithium3, "dilithium3" }, + { BCObjectIdentifiers.dilithium5, "dilithium5" }, + { BCObjectIdentifiers.dilithium2, "mldsa44" }, + { BCObjectIdentifiers.dilithium3, "mldsa65" }, + { BCObjectIdentifiers.dilithium5, "mldsa87" }, + { BCObjectIdentifiers.sphincsPlus_sha2_128f, "sphincssha2128fsimple" }, + { BCObjectIdentifiers.sphincsPlus_sha2_192f, "sphincssha2192fsimple" }, + { BCObjectIdentifiers.sphincsPlus_sha2_256f, "sphincssha2256fsimple" }, + }; + + public DerObjectIdentifier ClassicalAlgorithm { get; set; } + + public DerObjectIdentifier PostQuantumAlgorithm { get; set; } + + public DerObjectIdentifier HybridAlgorithm { get; set; } + + public string ClassicalName { get; set; } + + public string PostQuantumName { get; set; } + + public string HybridName { get; set; } + + public KeyGenerationParameters ClassicalParameters { get; set; } + + public KeyGenerationParameters PostQuantumParameters { get; set; } + + public HybridKeyGenerationParameters(SecureRandom random, DerObjectIdentifier classicalAlgorithm, DerObjectIdentifier postQuantumAlgorithm) + : base(random, 256) + { + if (!classicalOidToName.ContainsKey(classicalAlgorithm)) + { + throw new ArgumentException("Unsupported classical algorithm"); + } + if (!postQuantumOidToName.ContainsKey(postQuantumAlgorithm)) + { + throw new ArgumentException("Unsupported post-quantum algorithm"); + } + + ClassicalAlgorithm = classicalAlgorithm; + PostQuantumAlgorithm = postQuantumAlgorithm; + + ClassicalName = classicalOidToName[classicalAlgorithm]; + PostQuantumName = postQuantumOidToName[postQuantumAlgorithm]; + + SetHybrid(); + + InitializeParameters(); + } + + public HybridKeyGenerationParameters(SecureRandom random, string classicalAlgorithm, string postQuantumAlgorithm) + : base(random, 256) + { + classicalAlgorithm = classicalAlgorithm.ToLowerInvariant(); + postQuantumAlgorithm = postQuantumAlgorithm.ToLowerInvariant(); + + if (!classicalNameToOid.ContainsKey(classicalAlgorithm)) + { + throw new ArgumentException("Unsupported classical algorithm"); + } + if (!postQuantumNameToOid.ContainsKey(postQuantumAlgorithm)) + { + throw new ArgumentException("Unsupported post-quantum algorithm"); + } + + ClassicalName = classicalAlgorithm; + PostQuantumName = postQuantumAlgorithm; + + ClassicalAlgorithm = classicalNameToOid[classicalAlgorithm]; + PostQuantumAlgorithm = postQuantumNameToOid[postQuantumAlgorithm]; + + SetHybrid(); + + InitializeParameters(); + } + + public HybridKeyGenerationParameters(SecureRandom random, DerObjectIdentifier hybridAlgorithm) + : base(random, 256) + { + if (!HybridKeyParameters.HybridOidToName.ContainsKey(hybridAlgorithm.Id)) + { + throw new ArgumentException("Unsupported hybrid combination"); + } + + HybridName = HybridKeyParameters.HybridOidToName[hybridAlgorithm.Id]; + HybridAlgorithm = hybridAlgorithm; + + SetClassicals(); + + InitializeParameters(); + } + + public HybridKeyGenerationParameters(SecureRandom random, string hybridAlgorithm) + : base(random, 256) + { + hybridAlgorithm = hybridAlgorithm.ToLowerInvariant(); + + if (!HybridKeyParameters.HybridNameToOid.ContainsKey(hybridAlgorithm)) + { + throw new ArgumentException("Unsupported hybrid combination"); + } + + HybridName = hybridAlgorithm; + HybridAlgorithm = new DerObjectIdentifier(HybridKeyParameters.HybridNameToOid[hybridAlgorithm]); + + SetClassicals(); + + InitializeParameters(); + } + + private void SetClassicals() + { + var names = HybridName.Split(Convert.ToChar("_")); + ClassicalName = names[0]; + HybridName = names[1]; + + ClassicalAlgorithm = classicalNameToOid[ClassicalName]; + PostQuantumAlgorithm = postQuantumNameToOid[PostQuantumName]; + } + + private void SetHybrid() + { + HybridName = string.Concat(ClassicalName, "_", HybridName); + + if (!HybridKeyParameters.HybridNameToOid.ContainsKey(HybridName)) + { + throw new Exception("Unsupported hybrid combination"); + } + + HybridAlgorithm = new DerObjectIdentifier(HybridKeyParameters.HybridNameToOid[HybridName]); + } + + private void InitializeParameters() + { + switch (ClassicalName) + { + case "p256": + case "p384": + case "p512": + case "x25519": + case "x448": + case "ed25519": + case "ed448": + ClassicalParameters = new ECKeyGenerationParameters(ClassicalAlgorithm, new Security.SecureRandom()); + break; + } + + switch (PostQuantumName) + { + case "kyber512": + PostQuantumParameters = new KyberKeyGenerationParameters(new Security.SecureRandom(), KyberParameters.kyber512); + break; + case "kyber768": + PostQuantumParameters = new KyberKeyGenerationParameters(new Security.SecureRandom(), KyberParameters.kyber768); + break; + case "kyber1024": + PostQuantumParameters = new KyberKeyGenerationParameters(new Security.SecureRandom(), KyberParameters.kyber1024); + break; + case "mlkem512": + PostQuantumParameters = new KyberKeyGenerationParameters(new Security.SecureRandom(), KyberParameters.kyber512); + break; + case "mlkem768": + PostQuantumParameters = new KyberKeyGenerationParameters(new Security.SecureRandom(), KyberParameters.kyber768); + break; + case "mlkem1024": + PostQuantumParameters = new KyberKeyGenerationParameters(new Security.SecureRandom(), KyberParameters.kyber1024); + break; + case "dilithium2": + PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium2); + break; + case "dilithium3": + PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium3); + break; + case "dilithium5": + PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium5); + break; + case "mldsa44": + PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium2); + break; + case "mldsa65": + PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium3); + break; + case "mldsa87": + PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium5); + break; + case "sphincssha2128fsimple": + PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_128f_simple); + break; + case "sphincssha2192fsimple": + PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_192f_simple); + break; + case "sphincssha2256fsimple": + PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_256f_simple); + break; + } + } + } +} diff --git a/crypto/src/crypto/parameters/HybridKeyParameters.cs b/crypto/src/crypto/parameters/HybridKeyParameters.cs new file mode 100644 index 000000000..2c08ed126 --- /dev/null +++ b/crypto/src/crypto/parameters/HybridKeyParameters.cs @@ -0,0 +1,238 @@ +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math.EC.Custom.Sec; +using Org.BouncyCastle.Math.EC.Rfc7748; +using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; +using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; +using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Org.BouncyCastle.crypto.parameters +{ + public class HybridKeyParameters + : AsymmetricKeyParameter + { + public static readonly Dictionary HybridNameToOid = new Dictionary() + { + { "p256_kyber512" , "1.3.9999.99.72" }, + { "x25519_kyber512" , "1.3.9999.99.49" }, + { "p384_kyber768" , "1.3.9999.99.73" }, + { "x448_kyber768" , "1.3.9999.99.50" }, + { "x25519_kyber768" , "1.3.9999.99.51" }, + { "p256_kyber768" , "1.3.9999.99.52" }, + { "p521_kyber1024" , "1.3.9999.99.74" }, + { "p256_mlkem512" , "1.3.6.1.4.1.22554.5.7.1" }, + { "x25519_mlkem512" , "1.3.6.1.4.1.22554.5.8.1" }, + { "p384_mlkem768" , "1.3.9999.99.75" }, + { "x448_mlkem768" , "1.3.9999.99.53" }, + { "x25519_mlkem768" , "1.3.9999.99.54" }, + { "p256_mlkem768" , "1.3.9999.99.55" }, + { "p521_mlkem1024" , "1.3.9999.99.76" }, + { "p384_mlkem1024" , "1.3.6.1.4.1.42235.6" }, + { "p256_dilithium2" , "1.3.9999.2.7.1" }, + //{ "rsa3072_dilithium2" , "1.3.9999.2.7.2" }, + { "p384_dilithium3" , "1.3.9999.2.7.3" }, + { "p521_dilithium5" , "1.3.9999.2.7.4" }, + { "p256_mldsa44" , "1.3.9999.7.1" }, + //{ "rsa3072_mldsa44" , "1.3.9999.7.2" }, + //{ "mldsa44_rsa2048" , "2.16.840.1.114027.80.8.1.2" }, + { "ed25519_mldsa44" , "2.16.840.1.114027.80.8.1.3" }, + { "p256_mldsa44" , "2.16.840.1.114027.80.8.1.4" }, + { "p384_mldsa65" , "1.3.9999.7.3" }, + //{ "mldsa65_rsa3072" , "2.16.840.1.114027.80.8.1.7" }, + { "p256_mldsa65" , "2.16.840.1.114027.80.8.1.8" }, + { "ed25519_mldsa65" , "2.16.840.1.114027.80.8.1.10" }, + { "p521_mldsa87" , "1.3.9999.7.4" }, + { "p384_mldsa87" , "2.16.840.1.114027.80.8.1.11" }, + { "ed448_mldsa87" , "2.16.840.1.114027.80.8.1.13" }, + { "p256_sphincssha2128fsimple" , "1.3.9999.6.4.14" }, + //{ "rsa3072_sphincssha2128fsimple" , "1.3.9999.6.4.15" }, + { "p256_sphincssha2128ssimple" , "1.3.9999.6.4.17" }, + //{ "rsa3072_sphincssha2128ssimple" , "1.3.9999.6.4.18" }, + { "p384_sphincssha2192fsimple" , "1.3.9999.6.5.11" }, + { "p384_sphincssha2192ssimple" , "1.3.9999.6.5.13" }, + { "p521_sphincssha2256fsimple" , "1.3.9999.6.6.11" }, + { "p521_sphincssha2256ssimple" , "1.3.9999.6.6.13" }, + { "p256_sphincsshake128fsimple" , "1.3.9999.6.7.14" }, + //{ "rsa3072_sphincsshake128fsimple" , "1.3.9999.6.7.15" }, + { "p256_sphincsshake128ssimple" , "1.3.9999.6.7.17" }, + //{ "rsa3072_sphincsshake128ssimple" , "1.3.9999.6.7.18" }, + { "p384_sphincsshake192fsimple" , "1.3.9999.6.8.11" }, + { "p384_sphincsshake192ssimple" , "1.3.9999.6.8.13" }, + { "p521_sphincsshake256fsimple" , "1.3.9999.6.9.11" }, + { "p521_sphincsshake256ssimple" , "1.3.9999.6.9.13" }, + }; + + public static readonly Dictionary HybridOidToName = new Dictionary() + { + { "1.3.9999.99.72" , "p256_kyber512" }, + { "1.3.9999.99.49" , "x25519_kyber512" }, + { "1.3.9999.99.73" , "p384_kyber768" }, + { "1.3.9999.99.50" , "x448_kyber768" }, + { "1.3.9999.99.51" , "x25519_kyber768" }, + { "1.3.9999.99.52" , "p256_kyber768" }, + { "1.3.9999.99.74" , "p521_kyber1024" }, + { "1.3.6.1.4.1.22554.5.7.1" , "p256_mlkem512" }, + { "1.3.6.1.4.1.22554.5.8.1" , "x25519_mlkem512" }, + { "1.3.9999.99.75" , "p384_mlkem768" }, + { "1.3.9999.99.53" , "x448_mlkem768" }, + { "1.3.9999.99.54" , "x25519_mlkem768" }, + { "1.3.9999.99.55" , "p256_mlkem768" }, + { "1.3.9999.99.76" , "p521_mlkem1024" }, + { "1.3.6.1.4.1.42235.6" , "p384_mlkem1024" }, + { "1.3.9999.2.7.1" , "p256_dilithium2" }, + //{ "1.3.9999.2.7.2" , "rsa3072_dilithium2" }, + { "1.3.9999.2.7.3" , "p384_dilithium3" }, + { "1.3.9999.2.7.4" , "p521_dilithium5" }, + { "1.3.9999.7.1" , "p256_mldsa44" }, + //{ "1.3.9999.7.2" , "rsa3072_mldsa44" }, + //{ "2.16.840.1.114027.80.8.1.2" , "mldsa44_rsa2048" }, + { "2.16.840.1.114027.80.8.1.3" , "ed25519_mldsa44" }, + { "2.16.840.1.114027.80.8.1.4" , "p256_mldsa44" }, + { "1.3.9999.7.3" , "p384_mldsa65" }, + //{ "2.16.840.1.114027.80.8.1.7" , "mldsa65_rsa3072" }, + { "2.16.840.1.114027.80.8.1.8" , "p256_mldsa65" }, + { "2.16.840.1.114027.80.8.1.10" , "ed25519_mldsa65" }, + { "1.3.9999.7.4" , "p521_mldsa87" }, + { "2.16.840.1.114027.80.8.1.11" , "p384_mldsa87" }, + { "2.16.840.1.114027.80.8.1.13" , "ed448_mldsa87" }, + { "1.3.9999.6.4.14" , "p256_sphincssha2128fsimple" }, + //{ "1.3.9999.6.4.15" , "rsa3072_sphincssha2128fsimple" }, + { "1.3.9999.6.4.17" , "p256_sphincssha2128ssimple" }, + //{ "1.3.9999.6.4.18" , "rsa3072_sphincssha2128ssimple" }, + { "1.3.9999.6.5.11" , "p384_sphincssha2192fsimple" }, + { "1.3.9999.6.5.13" , "p384_sphincssha2192ssimple" }, + { "1.3.9999.6.6.11" , "p521_sphincssha2256fsimple" }, + { "1.3.9999.6.6.13" , "p521_sphincssha2256ssimple" }, + { "1.3.9999.6.7.14" , "p256_sphincsshake128fsimple" }, + //{ "1.3.9999.6.7.15" , "rsa3072_sphincsshake128fsimple" }, + { "1.3.9999.6.7.17" , "p256_sphincsshake128ssimple" }, + //{ "1.3.9999.6.7.18" , "rsa3072_sphincsshake128ssimple" }, + { "1.3.9999.6.8.11" , "p384_sphincsshake192fsimple" }, + { "1.3.9999.6.8.13" , "p384_sphincsshake192ssimple" }, + { "1.3.9999.6.9.11" , "p521_sphincsshake256fsimple" }, + { "1.3.9999.6.9.13" , "p521_sphincsshake256ssimple" }, + }; + + public readonly DerObjectIdentifier AlgorithmOid; + + public AsymmetricKeyParameter Classical { get; private set; } + + public AsymmetricKeyParameter PostQuantum { get; private set; } + + public string CanonicalName { get; private set; } + + public HybridKeyParameters(AsymmetricKeyParameter classical, AsymmetricKeyParameter postQuantum, DerObjectIdentifier oid = null) + : base(classical.IsPrivate) + { + if (classical.IsPrivate != postQuantum.IsPrivate) + throw new ArgumentException("Mixed private and public keys"); + + Classical = classical; + PostQuantum = postQuantum; + AlgorithmOid = null; + + if (oid != null) + { + AlgorithmOid = oid; + CanonicalName = null; + return; + } + + string classicalCanonicalName = null; + + //if (Classical is RsaKeyParameters) + //{ + //classicalCanonicalName = string.Concat("rsa", (Classical as RsaKeyParameters).Modulus.BitLength); + //} + else if (Classical is ECKeyParameters) + { + var curve = (Classical as ECKeyParameters).Parameters.Curve; + + if (curve is SecP256R1Curve) + { + classicalCanonicalName = "p256"; + } + else if (curve is SecP384R1Curve) + { + classicalCanonicalName = "p384"; + } + else if (curve is SecP521R1Curve) + { + classicalCanonicalName = "p521"; + } + } + else if (Classical is X25519PrivateKeyParameters || Classical is X25519PublicKeyParameters) + { + classicalCanonicalName = "x25519"; + } + else if (Classical is Ed25519PrivateKeyParameters || Classical is Ed25519PublicKeyParameters) + { + classicalCanonicalName = "ed25519"; + } + else if (Classical is X448PrivateKeyParameters || Classical is X448PublicKeyParameters) + { + classicalCanonicalName = "x448"; + } + else if (Classical is Ed448PrivateKeyParameters || Classical is Ed448PrivateKeyParameters) + { + classicalCanonicalName = "ed448"; + } + + string postQuantumCanonicalName = null; + + if (PostQuantum is KyberKeyParameters) + { + postQuantumCanonicalName = (PostQuantum as KyberKeyParameters).Parameters.Name; + } + else if (PostQuantum is DilithiumKeyParameters) + { + postQuantumCanonicalName = string.Concat("dilithium", (PostQuantum as DilithiumKeyParameters).Parameters.GetEngine(null).Mode.ToString()); + } + else if (PostQuantum is SphincsPlusKeyParameters) + { + postQuantumCanonicalName = (PostQuantum as SphincsPlusKeyParameters).Parameters.Name.Replace("-", ""); + } + + if (postQuantumCanonicalName != null && classicalCanonicalName != null) + { + CanonicalName = string.Concat(classicalCanonicalName, "_", postQuantumCanonicalName); + } + else + { + throw new Exception("Unsupported hybrid combination"); + } + + string objectId = null; + if (CanonicalName != null) + { + if(!HybridNameToOid.TryGetValue(CanonicalName, out objectId)) + { + throw new Exception("Object identifier for hybrid combination not found"); + } + } + + AlgorithmOid = new DerObjectIdentifier(objectId); + } + + public override bool Equals(object obj) + { + return (this == obj) || + (obj is HybridKeyParameters other && IsPrivate == other.IsPrivate && + Classical.Equals(other.Classical) && PostQuantum.Equals(other.PostQuantum)); + } + + public override int GetHashCode() + { + int hash = 17; + hash = hash * 23 + Classical.GetHashCode(); + hash = hash * 23 + PostQuantum.GetHashCode(); + return hash; + } + } +} diff --git a/crypto/src/pkcs/PrivateKeyInfoFactory.cs b/crypto/src/pkcs/PrivateKeyInfoFactory.cs index 95fcae20e..46d7b0562 100644 --- a/crypto/src/pkcs/PrivateKeyInfoFactory.cs +++ b/crypto/src/pkcs/PrivateKeyInfoFactory.cs @@ -9,6 +9,7 @@ using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.crypto.parameters; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; @@ -245,6 +246,11 @@ public static PrivateKeyInfo CreatePrivateKeyInfo(AsymmetricKeyParameter private new DerOctetString(key.GetEncoded()), attributes, key.GeneratePublicKey().GetEncoded()); } + if (privateKey is HybridKeyParameters) + { + // FIXME(bence) + } + throw new ArgumentException("Class provided is not convertible: " + Platform.GetTypeName(privateKey)); } diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs index ffda58062..e624a401e 100644 --- a/crypto/src/security/PrivateKeyFactory.cs +++ b/crypto/src/security/PrivateKeyFactory.cs @@ -12,6 +12,7 @@ using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.crypto.parameters; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; @@ -344,6 +345,10 @@ public static AsymmetricKeyParameter CreateKey( gostParams.EncryptionParamSet)); } + else if (HybridKeyParameters.HybridNameToOid.ContainsValue(algOid.Id)) + { + // FIXME(bence) + } else { throw new SecurityUtilityException("algorithm identifier in private key not recognised"); diff --git a/crypto/src/security/PublicKeyFactory.cs b/crypto/src/security/PublicKeyFactory.cs index c816e7b62..3f11b8066 100644 --- a/crypto/src/security/PublicKeyFactory.cs +++ b/crypto/src/security/PublicKeyFactory.cs @@ -11,6 +11,7 @@ using Org.BouncyCastle.Asn1.Rosstandart; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.crypto.parameters; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; @@ -273,6 +274,10 @@ public static AsymmetricKeyParameter CreateKey( return new ECPublicKeyParameters(q, ecDomainParameters); } + else if (HybridKeyParameters.HybridNameToOid.ContainsValue(algOid.Id)) + { + // FIXME(bence) + } else { throw new SecurityUtilityException("algorithm identifier in public key not recognised: " + algOid); diff --git a/crypto/src/x509/SubjectPublicKeyInfoFactory.cs b/crypto/src/x509/SubjectPublicKeyInfoFactory.cs index bfa20c866..a55d3403b 100644 --- a/crypto/src/x509/SubjectPublicKeyInfoFactory.cs +++ b/crypto/src/x509/SubjectPublicKeyInfoFactory.cs @@ -8,6 +8,7 @@ using Org.BouncyCastle.Asn1.Rosstandart; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.crypto.parameters; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; @@ -249,6 +250,11 @@ public static SubjectPublicKeyInfo CreateSubjectPublicKeyInfo( return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), key.GetEncoded()); } + if (publicKey is HybridKeyParameters) + { + // FIXME(bence) + } + throw new ArgumentException("Class provided no convertible: " + Platform.GetTypeName(publicKey)); } From e9b1183bfa4bcffa21e03ed70dca875e777c0d82 Mon Sep 17 00:00:00 2001 From: Bence Mali Date: Fri, 30 Aug 2024 12:35:01 +0200 Subject: [PATCH 02/10] hybrid signature generation/verification --- .../generators/HybridSignatureGenerator.cs | 133 +++++++++++++++++- 1 file changed, 131 insertions(+), 2 deletions(-) diff --git a/crypto/src/crypto/generators/HybridSignatureGenerator.cs b/crypto/src/crypto/generators/HybridSignatureGenerator.cs index dfc23d008..84d90c36c 100644 --- a/crypto/src/crypto/generators/HybridSignatureGenerator.cs +++ b/crypto/src/crypto/generators/HybridSignatureGenerator.cs @@ -2,13 +2,19 @@ using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Math.EC; using Org.BouncyCastle.Pqc.Crypto; using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Security; +using Org.BouncyCastle.Tls.Crypto.Impl.BC; +using Org.BouncyCastle.Utilities; using System; using System.Collections.Generic; using System.Linq; +using System.Numerics; +using System.Security; using System.Text; using System.Threading.Tasks; @@ -76,12 +82,135 @@ public AsymmetricCipherKeyPair GenerateKeyPair() public static byte[] GenerateSignature(AsymmetricKeyParameter privKey, byte[] message) { - // FIXME(bence) + if (!(privKey is HybridKeyParameters)) + { + throw new ArgumentException("Provided key parameter is not hybrid"); + } + if (!privKey.IsPrivate) + { + throw new ArgumentException("Provided key is not a private key"); + } + + var hybridPrivKey = privKey as HybridKeyParameters; + + byte[] classicalSignature = null; + if (hybridPrivKey.Classical is ECPrivateKeyParameters) + { + var signer = new ECDsaSigner(); + signer.Init(true, hybridPrivKey.Classical); + Math.BigInteger[] signature = signer.GenerateSignature(message); + classicalSignature = Arrays.Concatenate(signature[0].ToByteArrayUnsigned(), signature[1].ToByteArrayUnsigned()); + } + else if (hybridPrivKey.Classical is RsaKeyParameters) + { + // TODO + throw new NotImplementedException("Rsa hybrid signature generation not supported"); + } + + if (classicalSignature == null) + { + throw new Exception("Classical keytype not supported"); + } + + byte[] postQuantumSignature = null; + if (hybridPrivKey.PostQuantum is DilithiumKeyParameters) + { + var signer = new DilithiumSigner(); + signer.Init(true, hybridPrivKey.PostQuantum); + postQuantumSignature = signer.GenerateSignature(message); + } + else if (hybridPrivKey.PostQuantum is SphincsPlusKeyParameters) + { + var signer = new SphincsPlusSigner(); + signer.Init(true, hybridPrivKey.PostQuantum); + postQuantumSignature = signer.GenerateSignature(message); + } + + if (postQuantumSignature == null) + { + throw new Exception("Post-quantum keytype not supported"); + } + + return Arrays.Concatenate(classicalSignature, postQuantumSignature); } public static bool VerifySignature(AsymmetricKeyParameter pubKey, byte[] message, byte[] signature) { - // FIXME(bence) + if (!(pubKey is HybridKeyParameters)) + { + throw new ArgumentException("Provided key parameter is not hybrid"); + } + + var hybridPubKey = pubKey as HybridKeyParameters; + + bool classicalVerified = false; + if (hybridPubKey.Classical is ECPublicKeyParameters) + { + var domainParameters = (hybridPubKey.Classical as ECPublicKeyParameters).Parameters; + var classicalSignatureLength = (domainParameters.N.BitLength / 8) * 2; + + if (signature.Length <= classicalSignatureLength) + { + throw new Exception("Wrong size signature"); + } + + var classicalSignatureBytes = signature.Take(classicalSignatureLength).ToArray(); + var r = new Math.BigInteger(classicalSignatureBytes.Take(classicalSignatureLength / 2).ToArray()); + var s = new Math.BigInteger(classicalSignatureBytes.Skip(classicalSignatureLength / 2).ToArray()); + + var verifier = new ECDsaSigner(); + verifier.Init(false, hybridPubKey.Classical); + if(!verifier.VerifySignature(message, r, s)) + { + throw new VerificationException("Signature verification failed"); + } + + // take away classical signature + signature = signature.Skip(classicalSignatureLength).ToArray(); + + classicalVerified = true; + } + else if (hybridPubKey.Classical is RsaKeyParameters) + { + // TODO + throw new NotImplementedException("Rsa hybrid signature verification not supported"); + } + + if (!classicalVerified) + { + throw new Exception("Classical keytype not supported"); + } + + bool postQuantumVerified = false; + if (hybridPubKey.PostQuantum is DilithiumPublicKeyParameters) + { + var verifier = new DilithiumSigner(); + verifier.Init(false, hybridPubKey.PostQuantum); + if (!verifier.VerifySignature(message, signature)) + { + throw new VerificationException("Signature verification failed"); + } + + postQuantumVerified = true; + } + else if (hybridPubKey.PostQuantum is SphincsPlusPublicKeyParameters) + { + var verifier = new SphincsPlusSigner(); + verifier.Init(false, hybridPubKey.PostQuantum); + if (!verifier.VerifySignature(message, signature)) + { + throw new VerificationException("Signature verification failed"); + } + + postQuantumVerified = true; + } + + if (!postQuantumVerified) + { + throw new Exception("Post-quantum keytype not supported"); + } + + return true; } } } From f5457152449444a1523273b07cc28a7a03b08909 Mon Sep 17 00:00:00 2001 From: Bence Mali Date: Fri, 30 Aug 2024 15:44:12 +0200 Subject: [PATCH 03/10] public/private key factories done --- .../crypto/generators/HybridKemGenerator.cs | 122 +++++++++++++++--- .../generators/HybridSignatureGenerator.cs | 96 +++++++++++++- .../crypto/parameters/HybridKeyParameters.cs | 2 +- .../crystals/dilithium/DilithiumParameters.cs | 18 ++- crypto/src/security/PrivateKeyFactory.cs | 119 ++++++++++++++++- crypto/src/security/PublicKeyFactory.cs | 120 ++++++++++++++++- 6 files changed, 442 insertions(+), 35 deletions(-) diff --git a/crypto/src/crypto/generators/HybridKemGenerator.cs b/crypto/src/crypto/generators/HybridKemGenerator.cs index 8a9d70b30..6d7179509 100644 --- a/crypto/src/crypto/generators/HybridKemGenerator.cs +++ b/crypto/src/crypto/generators/HybridKemGenerator.cs @@ -48,6 +48,30 @@ public AsymmetricCipherKeyPair GenerateKeyPair() generator.Init(parameters.ClassicalParameters); classicalKeypair = generator.GenerateKeyPair(); } + else if (parameters.ClassicalParameters is X25519KeyGenerationParameters) + { + var generator = new X25519KeyPairGenerator(); + generator.Init(parameters.ClassicalParameters); + classicalKeypair = generator.GenerateKeyPair(); + } + else if (parameters.ClassicalParameters is Ed25519KeyGenerationParameters) + { + var generator = new Ed25519KeyPairGenerator(); + generator.Init(parameters.ClassicalParameters); + classicalKeypair = generator.GenerateKeyPair(); + } + else if (parameters.ClassicalParameters is X448KeyGenerationParameters) + { + var generator = new X448KeyPairGenerator(); + generator.Init(parameters.ClassicalParameters); + classicalKeypair = generator.GenerateKeyPair(); + } + else if (parameters.ClassicalParameters is Ed448KeyGenerationParameters) + { + var generator = new Ed448KeyPairGenerator(); + generator.Init(parameters.ClassicalParameters); + classicalKeypair = generator.GenerateKeyPair(); + } else if (parameters.ClassicalParameters is RsaKeyGenerationParameters) { // TODO @@ -86,19 +110,49 @@ public static ISecretWithEncapsulation Encapsulate(AsymmetricKeyParameter pubKey byte[] classicalCiphertext = null; byte[] classicalSharedSecret = null; - if (hybridPubKey.Classical is ECPublicKeyParameters) + if (hybridPubKey.Classical is ECPublicKeyParameters ecPublicKey) { var generator = new ECKeyPairGenerator("ECDH"); - var pubInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(hybridPubKey.Classical); + var pubInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(ecPublicKey); var parameters = new ECKeyGenerationParameters(pubInfo.Algorithm.Algorithm, new SecureRandom()); generator.Init(parameters); var ephemeralKeypair = generator.GenerateKeyPair(); classicalCiphertext = (ephemeralKeypair.Public as ECPublicKeyParameters).Q.GetEncoded(); - var ecdhAgreement = new ECDHBasicAgreement(); - ecdhAgreement.Init(ephemeralKeypair.Private); - classicalSharedSecret = ecdhAgreement.CalculateAgreement(hybridPubKey.Classical).ToByteArrayUnsigned(); + var agreement = new ECDHBasicAgreement(); + agreement.Init(ephemeralKeypair.Private); + classicalSharedSecret = agreement.CalculateAgreement(ecPublicKey).ToByteArrayUnsigned(); + } + else if (hybridPubKey.Classical is X25519PublicKeyParameters x25519PublicKey) + { + var generator = new X25519KeyPairGenerator(); + var pubInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(x25519PublicKey); + var parameters = new X25519KeyGenerationParameters(new SecureRandom()); + generator.Init(parameters); + var ephemeralKeypair = generator.GenerateKeyPair(); + + classicalCiphertext = (ephemeralKeypair.Public as X25519PublicKeyParameters).GetEncoded(); + + var agreement = new X25519Agreement(); + agreement.Init(ephemeralKeypair.Private); + classicalSharedSecret = new byte[agreement.AgreementSize]; + agreement.CalculateAgreement(x25519PublicKey, classicalSharedSecret, 0); + } + else if (hybridPubKey.Classical is X448PublicKeyParameters x448PublicKey) + { + var generator = new X448KeyPairGenerator(); + var pubInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(x448PublicKey); + var parameters = new X448KeyGenerationParameters(new SecureRandom()); + generator.Init(parameters); + var ephemeralKeypair = generator.GenerateKeyPair(); + + classicalCiphertext = (ephemeralKeypair.Public as X448PublicKeyParameters).GetEncoded(); + + var agreement = new X448Agreement(); + agreement.Init(ephemeralKeypair.Private); + classicalSharedSecret = new byte[agreement.AgreementSize]; + agreement.CalculateAgreement(x448PublicKey, classicalSharedSecret, 0); } else if (hybridPubKey.Classical is RsaKeyParameters) { @@ -142,12 +196,10 @@ public static byte[] Decapsulate(AsymmetricKeyParameter privKey, byte[] cipherte var hybridPrivKey = privKey as HybridKeyParameters; byte[] classicalSharedSecret = null; - if (hybridPrivKey.Classical is ECPrivateKeyParameters) + if (hybridPrivKey.Classical is ECPrivateKeyParameters ecPrivateKey) { - var classical = hybridPrivKey.Classical as ECPrivateKeyParameters; - // public key is uncompressed ec point - var publicKeySize = (classical.Parameters.Curve.FieldElementEncodingLength * 2) + 1; + var publicKeySize = (ecPrivateKey.Parameters.Curve.FieldElementEncodingLength * 2) + 1; if (ciphertext.Length <= publicKeySize) { @@ -155,15 +207,53 @@ public static byte[] Decapsulate(AsymmetricKeyParameter privKey, byte[] cipherte } var publicKeyBytes = ciphertext.Take(publicKeySize).ToArray(); - var otherPublicKey = new ECPublicKeyParameters(classical.Parameters.Curve.DecodePoint(publicKeyBytes), classical.Parameters); + var otherPublicKey = new ECPublicKeyParameters(ecPrivateKey.Parameters.Curve.DecodePoint(publicKeyBytes), ecPrivateKey.Parameters); - var ecdhAgreement = new ECDHBasicAgreement(); - ecdhAgreement.Init(classical); - classicalSharedSecret = ecdhAgreement.CalculateAgreement(otherPublicKey).ToByteArrayUnsigned(); + var agreement = new ECDHBasicAgreement(); + agreement.Init(ecPrivateKey); + classicalSharedSecret = agreement.CalculateAgreement(otherPublicKey).ToByteArrayUnsigned(); // take away classical ciphertext ciphertext = ciphertext.Skip(publicKeySize).ToArray(); } + else if (hybridPrivKey.Classical is X25519PrivateKeyParameters x25519PrivateKey) + { + var publicKeySize = X25519PrivateKeyParameters.KeySize; + + if (ciphertext.Length <= publicKeySize) + { + throw new Exception("Wrong size classical ciphertext"); + } + + var publicKeyBytes = ciphertext.Take(publicKeySize).ToArray(); + var otherPublicKey = new X25519PublicKeyParameters(publicKeyBytes); + + var agreement = new X25519Agreement(); + agreement.Init(x25519PrivateKey); + classicalSharedSecret = new byte[agreement.AgreementSize]; + agreement.CalculateAgreement(otherPublicKey, classicalSharedSecret, 0); + + ciphertext = ciphertext.Skip(publicKeySize).ToArray(); + } + else if (hybridPrivKey.Classical is X448PrivateKeyParameters x448PrivateKey) + { + var publicKeySize = X448PrivateKeyParameters.KeySize; + + if (ciphertext.Length <= publicKeySize) + { + throw new Exception("Wrong size classical ciphertext"); + } + + var publicKeyBytes = ciphertext.Take(publicKeySize).ToArray(); + var otherPublicKey = new X448PublicKeyParameters(publicKeyBytes); + + var agreement = new X448Agreement(); + agreement.Init(x448PrivateKey); + classicalSharedSecret = new byte[agreement.AgreementSize]; + agreement.CalculateAgreement(otherPublicKey, classicalSharedSecret, 0); + + ciphertext = ciphertext.Skip(publicKeySize).ToArray(); + } else if (hybridPrivKey.Classical is RsaKeyParameters) { // TODO @@ -176,14 +266,14 @@ public static byte[] Decapsulate(AsymmetricKeyParameter privKey, byte[] cipherte } byte[] postQuantumSharedSecret = null; - if (hybridPrivKey.PostQuantum is KyberPrivateKeyParameters) + if (hybridPrivKey.PostQuantum is KyberPrivateKeyParameters postQuantum) { - var extractor = new KyberKemExtractor(hybridPrivKey.PostQuantum as KyberPrivateKeyParameters); + var extractor = new KyberKemExtractor(postQuantum); if (ciphertext.Length != extractor.EncapsulationLength) { throw new Exception("Wrong size post-quantum ciphertext"); } - postQuantumSharedSecret = new KyberKemExtractor(hybridPrivKey.PostQuantum as KyberPrivateKeyParameters).ExtractSecret(ciphertext); + postQuantumSharedSecret = new KyberKemExtractor(postQuantum).ExtractSecret(ciphertext); } if (postQuantumSharedSecret == null) diff --git a/crypto/src/crypto/generators/HybridSignatureGenerator.cs b/crypto/src/crypto/generators/HybridSignatureGenerator.cs index 84d90c36c..8341f4f45 100644 --- a/crypto/src/crypto/generators/HybridSignatureGenerator.cs +++ b/crypto/src/crypto/generators/HybridSignatureGenerator.cs @@ -4,6 +4,7 @@ using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Signers; using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Rfc8032; using Org.BouncyCastle.Pqc.Crypto; using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; @@ -47,6 +48,30 @@ public AsymmetricCipherKeyPair GenerateKeyPair() generator.Init(parameters.ClassicalParameters); classicalKeypair = generator.GenerateKeyPair(); } + else if (parameters.ClassicalParameters is X25519KeyGenerationParameters) + { + var generator = new X25519KeyPairGenerator(); + generator.Init(parameters.ClassicalParameters); + classicalKeypair = generator.GenerateKeyPair(); + } + else if (parameters.ClassicalParameters is Ed25519KeyGenerationParameters) + { + var generator = new Ed25519KeyPairGenerator(); + generator.Init(parameters.ClassicalParameters); + classicalKeypair = generator.GenerateKeyPair(); + } + else if (parameters.ClassicalParameters is X448KeyGenerationParameters) + { + var generator = new X448KeyPairGenerator(); + generator.Init(parameters.ClassicalParameters); + classicalKeypair = generator.GenerateKeyPair(); + } + else if (parameters.ClassicalParameters is Ed448KeyGenerationParameters) + { + var generator = new Ed448KeyPairGenerator(); + generator.Init(parameters.ClassicalParameters); + classicalKeypair = generator.GenerateKeyPair(); + } else if (parameters.ClassicalParameters is RsaKeyGenerationParameters) { // TODO @@ -94,13 +119,27 @@ public static byte[] GenerateSignature(AsymmetricKeyParameter privKey, byte[] me var hybridPrivKey = privKey as HybridKeyParameters; byte[] classicalSignature = null; - if (hybridPrivKey.Classical is ECPrivateKeyParameters) + if (hybridPrivKey.Classical is ECPrivateKeyParameters ecPrivKey) { var signer = new ECDsaSigner(); - signer.Init(true, hybridPrivKey.Classical); - Math.BigInteger[] signature = signer.GenerateSignature(message); + signer.Init(true, ecPrivKey); + var signature = signer.GenerateSignature(message); classicalSignature = Arrays.Concatenate(signature[0].ToByteArrayUnsigned(), signature[1].ToByteArrayUnsigned()); } + else if (hybridPrivKey.Classical is Ed25519PrivateKeyParameters ed25519PrivKey) + { + var signer = new Ed25519Signer(); + signer.Init(true, ed25519PrivKey); + signer.BlockUpdate(message, 0, message.Length); + classicalSignature = signer.GenerateSignature(); + } + else if (hybridPrivKey.Classical is Ed448PrivateKeyParameters ed448PrivKey) + { + var signer = new Ed448Signer(message); + signer.Init(true, ed448PrivKey); + signer.BlockUpdate(message, 0, message.Length); + classicalSignature = signer.GenerateSignature(); + } else if (hybridPrivKey.Classical is RsaKeyParameters) { // TODO @@ -144,9 +183,9 @@ public static bool VerifySignature(AsymmetricKeyParameter pubKey, byte[] message var hybridPubKey = pubKey as HybridKeyParameters; bool classicalVerified = false; - if (hybridPubKey.Classical is ECPublicKeyParameters) + if (hybridPubKey.Classical is ECPublicKeyParameters ecPublicKey) { - var domainParameters = (hybridPubKey.Classical as ECPublicKeyParameters).Parameters; + var domainParameters = ecPublicKey.Parameters; var classicalSignatureLength = (domainParameters.N.BitLength / 8) * 2; if (signature.Length <= classicalSignatureLength) @@ -170,6 +209,53 @@ public static bool VerifySignature(AsymmetricKeyParameter pubKey, byte[] message classicalVerified = true; } + else if (hybridPubKey.Classical is Ed25519PublicKeyParameters ed25519PublicKey) + { + var classicalSignatureLength = Ed25519.SignatureSize; + + if (signature.Length <= classicalSignatureLength) + { + throw new Exception("Wrong size signature"); + } + + var classicalSignatureBytes = signature.Take(classicalSignatureLength).ToArray(); + + var verifier = new Ed25519Signer(); + verifier.Init(true, ed25519PublicKey); + verifier.BlockUpdate(message, 0, message.Length); + if(!verifier.VerifySignature(signature)) + { + throw new VerificationException("Signature verification failed"); + } + + // take away classical signature + signature = signature.Skip(classicalSignatureLength).ToArray(); + + classicalVerified = true; + } + else if (hybridPubKey.Classical is Ed448PublicKeyParameters ed448PublicKey) + { + var classicalSignatureLength = Ed448.SignatureSize; + + if (signature.Length <= classicalSignatureLength) + { + throw new Exception("Wrong size signature"); + } + + var classicalSignatureBytes = signature.Take(classicalSignatureLength).ToArray(); + + var verifier = new Ed448Signer(message); + verifier.Init(true, ed448PublicKey); + if(!verifier.VerifySignature(signature)) + { + throw new VerificationException("Signature verification failed"); + } + + // take away classical signature + signature = signature.Skip(classicalSignatureLength).ToArray(); + + classicalVerified = true; + } else if (hybridPubKey.Classical is RsaKeyParameters) { // TODO diff --git a/crypto/src/crypto/parameters/HybridKeyParameters.cs b/crypto/src/crypto/parameters/HybridKeyParameters.cs index 2c08ed126..424ec8326 100644 --- a/crypto/src/crypto/parameters/HybridKeyParameters.cs +++ b/crypto/src/crypto/parameters/HybridKeyParameters.cs @@ -150,7 +150,7 @@ public HybridKeyParameters(AsymmetricKeyParameter classical, AsymmetricKeyParame //{ //classicalCanonicalName = string.Concat("rsa", (Classical as RsaKeyParameters).Modulus.BitLength); //} - else if (Classical is ECKeyParameters) + if (Classical is ECKeyParameters) { var curve = (Classical as ECKeyParameters).Parameters.Curve; diff --git a/crypto/src/pqc/crypto/crystals/dilithium/DilithiumParameters.cs b/crypto/src/pqc/crypto/crystals/dilithium/DilithiumParameters.cs index 4636fe6b0..14ded959d 100644 --- a/crypto/src/pqc/crypto/crystals/dilithium/DilithiumParameters.cs +++ b/crypto/src/pqc/crypto/crystals/dilithium/DilithiumParameters.cs @@ -7,23 +7,25 @@ namespace Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium public sealed class DilithiumParameters : ICipherParameters { - public static DilithiumParameters Dilithium2 = new DilithiumParameters(2, false); + public static DilithiumParameters Dilithium2 = new DilithiumParameters("dilithium2", 2, false); [Obsolete("Parameter set to be removed")] - public static DilithiumParameters Dilithium2Aes = new DilithiumParameters(2, true); + public static DilithiumParameters Dilithium2Aes = new DilithiumParameters("dilithium2aes", 2, true); - public static DilithiumParameters Dilithium3 = new DilithiumParameters(3, false); + public static DilithiumParameters Dilithium3 = new DilithiumParameters("dilithium3", 3, false); [Obsolete("Parameter set to be removed")] - public static DilithiumParameters Dilithium3Aes = new DilithiumParameters(3, true); + public static DilithiumParameters Dilithium3Aes = new DilithiumParameters("dilithium3aes", 3, true); - public static DilithiumParameters Dilithium5 = new DilithiumParameters(5, false); + public static DilithiumParameters Dilithium5 = new DilithiumParameters("dilithium5", 5, false); [Obsolete("Parameter set to be removed")] - public static DilithiumParameters Dilithium5Aes = new DilithiumParameters(5, true); + public static DilithiumParameters Dilithium5Aes = new DilithiumParameters("dilithium5aes", 5, true); + private string name; private int k; private bool usingAes; - private DilithiumParameters(int param, bool usingAes) + private DilithiumParameters(string name, int param, bool usingAes) { + this.name = name; k = param; this.usingAes = usingAes; } @@ -32,5 +34,7 @@ internal DilithiumEngine GetEngine(SecureRandom Random) { return new DilithiumEngine(k, Random, usingAes); } + + public string Name => name; } } \ No newline at end of file diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs index e624a401e..8f98995f5 100644 --- a/crypto/src/security/PrivateKeyFactory.cs +++ b/crypto/src/security/PrivateKeyFactory.cs @@ -1,6 +1,6 @@ using System; using System.IO; - +using System.Linq; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cryptlib; using Org.BouncyCastle.Asn1.CryptoPro; @@ -18,6 +18,10 @@ using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; +using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; +using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; +using Org.BouncyCastle.Pqc.Crypto.Utilities; namespace Org.BouncyCastle.Security { @@ -345,9 +349,118 @@ public static AsymmetricKeyParameter CreateKey( gostParams.EncryptionParamSet)); } - else if (HybridKeyParameters.HybridNameToOid.ContainsValue(algOid.Id)) + else if (HybridKeyParameters.HybridOidToName.ContainsKey(algOid.Id)) { - // FIXME(bence) + var hybridName = HybridKeyParameters.HybridOidToName[algOid.Id]; + var names = hybridName.Split(Convert.ToChar("_")); + var classicalName = names[0]; + var postQuantumName = names[1]; + + var keyParameters = new HybridKeyGenerationParameters(new SecureRandom(), classicalName, postQuantumName); + + int classicalKeySize = 0; + if (keyParameters.ClassicalParameters is ECKeyGenerationParameters ecKeyParameters) + { + classicalKeySize = ecKeyParameters.DomainParameters.Curve.FieldElementEncodingLength; + } + else if (keyParameters.ClassicalParameters is X25519KeyGenerationParameters) + { + classicalKeySize = X25519PrivateKeyParameters.KeySize; + } + else if (keyParameters.ClassicalParameters is Ed25519KeyGenerationParameters) + { + classicalKeySize = Ed25519PrivateKeyParameters.KeySize; + } + else if (keyParameters.ClassicalParameters is X448KeyGenerationParameters) + { + classicalKeySize = X448PrivateKeyParameters.KeySize; + } + else if (keyParameters.ClassicalParameters is Ed448KeyGenerationParameters) + { + classicalKeySize = Ed448PrivateKeyParameters.KeySize; + } + else if (keyParameters.ClassicalParameters is RsaKeyGenerationParameters) + { + // TODO + throw new Exception("Rsa hybrid keys not supported"); + } + + if (classicalKeySize == 0) + { + throw new Exception("Classical keytype not supported"); + } + + int postQuantumKeySize = 0; + if (keyParameters.PostQuantumParameters is KyberKeyGenerationParameters kyberParameters) + { + switch (kyberParameters.Parameters.Name) + { + case "kyber512": + postQuantumKeySize = 1632; + break; + case "kyber768": + postQuantumKeySize = 2400; + break; + case "kyber1024": + postQuantumKeySize = 3168; + break; + } + } + else if (keyParameters.PostQuantumParameters is DilithiumKeyGenerationParameters dilithiumParameters) + { + switch (dilithiumParameters.Parameters.Name) + { + case "dilithium2": + postQuantumKeySize = 2560; + break; + case "dilithium3": + postQuantumKeySize = 4032; + break; + case "dilithium5": + postQuantumKeySize = 4896; + break; + } + } + else if (keyParameters.PostQuantumParameters is SphincsPlusKeyGenerationParameters sphincsParameters) + { + switch (sphincsParameters.Parameters.Name) + { + case "sha2-128f-simple": + postQuantumKeySize = 64; + break; + case "sha2-192f-simple": + postQuantumKeySize = 96; + break; + case "sha2-256f-simple": + postQuantumKeySize = 128; + break; + } + } + + if (postQuantumKeySize == 0) + { + throw new Exception("Post-quantum keytype not supported"); + } + + // expected format: + // first 4 bytes are length of the classical private key + // then comes the classical private key + // finally the post-quantum private key + var hybridBytes = keyInfo.PrivateKey.GetOctets(); + + // deliberately ignoring classical keysize encoding + if (hybridBytes.Length != 4 + classicalKeySize + postQuantumKeySize) + { + throw new Exception("Encoded hybrid private key has wrong size"); + } + + var classicalBytes = hybridBytes.Skip(4).Take(classicalKeySize).ToArray(); + var postQuantumBytes = hybridBytes.Skip(4).Skip(classicalKeySize).ToArray(); + + var classicalKeyParameter = PrivateKeyFactory.CreateKey(classicalBytes); + var postQuantumKeyParameter = PqcPrivateKeyFactory.CreateKey(postQuantumBytes); + + return new HybridKeyParameters(classicalKeyParameter, postQuantumKeyParameter); } else { diff --git a/crypto/src/security/PublicKeyFactory.cs b/crypto/src/security/PublicKeyFactory.cs index 3f11b8066..cabcae758 100644 --- a/crypto/src/security/PublicKeyFactory.cs +++ b/crypto/src/security/PublicKeyFactory.cs @@ -1,6 +1,6 @@ using System; using System.IO; - +using System.Linq; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cryptlib; using Org.BouncyCastle.Asn1.CryptoPro; @@ -17,6 +17,10 @@ using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; +using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; +using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; +using Org.BouncyCastle.Pqc.Crypto.Utilities; using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Security @@ -274,9 +278,119 @@ public static AsymmetricKeyParameter CreateKey( return new ECPublicKeyParameters(q, ecDomainParameters); } - else if (HybridKeyParameters.HybridNameToOid.ContainsValue(algOid.Id)) + else if (HybridKeyParameters.HybridOidToName.ContainsKey(algOid.Id)) { - // FIXME(bence) + var hybridName = HybridKeyParameters.HybridOidToName[algOid.Id]; + var names = hybridName.Split(Convert.ToChar("_")); + var classicalName = names[0]; + var postQuantumName = names[1]; + + var keyParameters = new HybridKeyGenerationParameters(new SecureRandom(), classicalName, postQuantumName); + + int classicalKeySize = 0; + if (keyParameters.ClassicalParameters is ECKeyGenerationParameters ecKeyParameters) + { + // public key is uncompressed ec point + classicalKeySize = (ecKeyParameters.DomainParameters.Curve.FieldElementEncodingLength * 2) + 1; + } + else if (keyParameters.ClassicalParameters is X25519KeyGenerationParameters) + { + classicalKeySize = X25519PublicKeyParameters.KeySize; + } + else if (keyParameters.ClassicalParameters is Ed25519KeyGenerationParameters) + { + classicalKeySize = Ed25519PublicKeyParameters.KeySize; + } + else if (keyParameters.ClassicalParameters is X448KeyGenerationParameters) + { + classicalKeySize = X448PublicKeyParameters.KeySize; + } + else if (keyParameters.ClassicalParameters is Ed448KeyGenerationParameters) + { + classicalKeySize = Ed448PublicKeyParameters.KeySize; + } + else if (keyParameters.ClassicalParameters is RsaKeyGenerationParameters) + { + // TODO + throw new Exception("Rsa hybrid keys not supported"); + } + + if (classicalKeySize == 0) + { + throw new Exception("Classical keytype not supported"); + } + + int postQuantumKeySize = 0; + if (keyParameters.PostQuantumParameters is KyberKeyGenerationParameters kyberParameters) + { + switch (kyberParameters.Parameters.Name) + { + case "kyber512": + postQuantumKeySize = 800; + break; + case "kyber768": + postQuantumKeySize = 1184; + break; + case "kyber1024": + postQuantumKeySize = 1568; + break; + } + } + else if (keyParameters.PostQuantumParameters is DilithiumKeyGenerationParameters dilithiumParameters) + { + switch (dilithiumParameters.Parameters.Name) + { + case "dilithium2": + postQuantumKeySize = 1312; + break; + case "dilithium3": + postQuantumKeySize = 1952; + break; + case "dilithium5": + postQuantumKeySize = 2592; + break; + } + } + else if (keyParameters.PostQuantumParameters is SphincsPlusKeyGenerationParameters sphincsParameters) + { + switch (sphincsParameters.Parameters.Name) + { + case "sha2-128f-simple": + postQuantumKeySize = 32; + break; + case "sha2-192f-simple": + postQuantumKeySize = 48; + break; + case "sha2-256f-simple": + postQuantumKeySize = 64; + break; + } + } + + if (postQuantumKeySize == 0) + { + throw new Exception("Post-quantum keytype not supported"); + } + + // expected format: + // first 4 bytes are length of the classical public key + // then comes the classical public key + // finally the post-quantum public key + var hybridBytes = keyInfo.PublicKey.GetBytes(); + + // deliberately ignoring classical keysize encoding + if (hybridBytes.Length != 4 + classicalKeySize + postQuantumKeySize) + { + throw new Exception("Encoded hybrid public key has wrong size"); + } + + var classicalBytes = hybridBytes.Skip(4).Take(classicalKeySize).ToArray(); + var postQuantumBytes = hybridBytes.Skip(4).Skip(classicalKeySize).ToArray(); + + var classicalKeyParameter = PublicKeyFactory.CreateKey(classicalBytes); + var postQuantumKeyParameter = PqcPublicKeyFactory.CreateKey(postQuantumBytes); + + return new HybridKeyParameters(classicalKeyParameter, postQuantumKeyParameter); } else { From f1b04574a9990cee308f49018f4b01671fcbda0a Mon Sep 17 00:00:00 2001 From: Bence Mali Date: Mon, 9 Sep 2024 16:16:34 +0200 Subject: [PATCH 04/10] PrivateKeyInfoFactory and SubjectPublicKeyInfoFactory updated --- .../HybridKeyGenerationParameters.cs | 122 ++++++++++-------- .../crypto/parameters/HybridKeyParameters.cs | 2 +- crypto/src/pkcs/PrivateKeyInfoFactory.cs | 97 +++++++++++++- .../src/x509/SubjectPublicKeyInfoFactory.cs | 76 ++++++++++- 4 files changed, 242 insertions(+), 55 deletions(-) diff --git a/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs b/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs index ab852f1d8..a6c9fd5d6 100644 --- a/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs +++ b/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs @@ -1,6 +1,7 @@ using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.BC; using Org.BouncyCastle.Asn1.EdEC; +using Org.BouncyCastle.Asn1.Nist; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Crypto; @@ -44,40 +45,46 @@ public class HybridKeyGenerationParameters public Dictionary postQuantumNameToOid = new Dictionary() { - { "kyber512", BCObjectIdentifiers.kyber512 }, - { "kyber768", BCObjectIdentifiers.kyber768 }, - { "kyber1024", BCObjectIdentifiers.kyber1024 }, - { "mlkem512", BCObjectIdentifiers.kyber512 }, - { "mlkem768", BCObjectIdentifiers.kyber768 }, - { "mlkem1024", BCObjectIdentifiers.kyber1024 }, - { "dilithium2", BCObjectIdentifiers.dilithium2 }, - { "dilithium3", BCObjectIdentifiers.dilithium3 }, - { "dilithium5", BCObjectIdentifiers.dilithium5 }, - { "mldsa44", BCObjectIdentifiers.dilithium2 }, - { "mldsa65", BCObjectIdentifiers.dilithium3 }, - { "mldsa87", BCObjectIdentifiers.dilithium5 }, - { "sphincssha2128fsimple", BCObjectIdentifiers.sphincsPlus_sha2_128f }, - { "sphincssha2192fsimple", BCObjectIdentifiers.sphincsPlus_sha2_192f }, - { "sphincssha2256fsimple", BCObjectIdentifiers.sphincsPlus_sha2_256f }, + { "mlkem512", NistObjectIdentifiers.IdAlgMLKem512 }, + { "mlkem768", NistObjectIdentifiers.IdAlgMLKem768 }, + { "mlkem1024", NistObjectIdentifiers.IdAlgMLKem1024 }, + { "mldsa44", NistObjectIdentifiers.IdHashMLDsa44WithSha512 }, + { "mldsa65", NistObjectIdentifiers.IdHashMLDsa65WithSha512 }, + { "mldsa87", NistObjectIdentifiers.IdHashMLDsa87WithSha512 }, + { "slh_dsa_sha2_128f", NistObjectIdentifiers.IdHashSlhDsasha2_128fWithSha256 }, + { "slh_dsa_sha2_192f", NistObjectIdentifiers.IdHashSlhDsasha2_192fWithSha512 }, + { "slh_dsa_sha2_256f", NistObjectIdentifiers.IdHashSlhDsasha2_256fWithSha512 }, + { "slh_dsa_sha2_128s", NistObjectIdentifiers.IdHashSlhDsaSha2_128sWithSha256 }, + { "slh_dsa_sha2_192s", NistObjectIdentifiers.IdHashSlhDsasha2_192sWithSha512 }, + { "slh_dsa_sha2_256s", NistObjectIdentifiers.IdHashSlhDsasha2_256sWithSha512 }, + { "slh_dsa_shake_128f", NistObjectIdentifiers.IdHashSlhDsashake_128fWithShake128 }, + { "slh_dsa_shake_192f", NistObjectIdentifiers.IdHashSlhDsashake_192fWithShake256 }, + { "slh_dsa_shake_256f", NistObjectIdentifiers.IdHashSlhDsashake_256fWithShake256 }, + { "slh_dsa_shake_128s", NistObjectIdentifiers.IdHashSlhDsashake_128sWithShake128 }, + { "slh_dsa_shake_192s", NistObjectIdentifiers.IdHashSlhDsashake_192sWithShake256 }, + { "slh_dsa_shake_256s", NistObjectIdentifiers.IdHashSlhDsashake_256sWithShake256 }, }; public Dictionary postQuantumOidToName = new Dictionary() { - { BCObjectIdentifiers.kyber512, "kyber512" }, - { BCObjectIdentifiers.kyber768, "kyber768" }, - { BCObjectIdentifiers.kyber1024, "kyber1024" }, - { BCObjectIdentifiers.kyber512, "mlkem512" }, - { BCObjectIdentifiers.kyber768, "mlkem768" }, - { BCObjectIdentifiers.kyber1024, "mlkem1024" }, - { BCObjectIdentifiers.dilithium2, "dilithium2" }, - { BCObjectIdentifiers.dilithium3, "dilithium3" }, - { BCObjectIdentifiers.dilithium5, "dilithium5" }, - { BCObjectIdentifiers.dilithium2, "mldsa44" }, - { BCObjectIdentifiers.dilithium3, "mldsa65" }, - { BCObjectIdentifiers.dilithium5, "mldsa87" }, - { BCObjectIdentifiers.sphincsPlus_sha2_128f, "sphincssha2128fsimple" }, - { BCObjectIdentifiers.sphincsPlus_sha2_192f, "sphincssha2192fsimple" }, - { BCObjectIdentifiers.sphincsPlus_sha2_256f, "sphincssha2256fsimple" }, + { NistObjectIdentifiers.IdAlgMLKem512, "mlkem512" }, + { NistObjectIdentifiers.IdAlgMLKem768 , "mlkem768" }, + { NistObjectIdentifiers.IdAlgMLKem1024 , "mlkem1024" }, + { NistObjectIdentifiers.IdHashMLDsa44WithSha512 , "mldsa44" }, + { NistObjectIdentifiers.IdHashMLDsa65WithSha512 , "mldsa65" }, + { NistObjectIdentifiers.IdHashMLDsa87WithSha512 , "mldsa87" }, + { NistObjectIdentifiers.IdHashSlhDsasha2_128fWithSha256 , "slh_dsa_sha2_128f" }, + { NistObjectIdentifiers.IdHashSlhDsasha2_192fWithSha512 , "slh_dsa_sha2_192f" }, + { NistObjectIdentifiers.IdHashSlhDsasha2_256fWithSha512 , "slh_dsa_sha2_256f" }, + { NistObjectIdentifiers.IdHashSlhDsaSha2_128sWithSha256 , "slh_dsa_sha2_128s" }, + { NistObjectIdentifiers.IdHashSlhDsasha2_192sWithSha512 , "slh_dsa_sha2_192s" }, + { NistObjectIdentifiers.IdHashSlhDsasha2_256sWithSha512 , "slh_dsa_sha2_256s" }, + { NistObjectIdentifiers.IdHashSlhDsashake_128fWithShake128 , "slh_dsa_shake_128f" }, + { NistObjectIdentifiers.IdHashSlhDsashake_192fWithShake256 , "slh_dsa_shake_192f" }, + { NistObjectIdentifiers.IdHashSlhDsashake_256fWithShake256 , "slh_dsa_shake_256f" }, + { NistObjectIdentifiers.IdHashSlhDsashake_128sWithShake128 , "slh_dsa_shake_128s" }, + { NistObjectIdentifiers.IdHashSlhDsashake_192sWithShake256 , "slh_dsa_shake_192s" }, + { NistObjectIdentifiers.IdHashSlhDsashake_256sWithShake256 , "slh_dsa_shake_256s" }, }; public DerObjectIdentifier ClassicalAlgorithm { get; set; } @@ -214,19 +221,12 @@ private void InitializeParameters() case "ed448": ClassicalParameters = new ECKeyGenerationParameters(ClassicalAlgorithm, new Security.SecureRandom()); break; + default: + throw new Exception("Classical algorithm not supported"); } switch (PostQuantumName) { - case "kyber512": - PostQuantumParameters = new KyberKeyGenerationParameters(new Security.SecureRandom(), KyberParameters.kyber512); - break; - case "kyber768": - PostQuantumParameters = new KyberKeyGenerationParameters(new Security.SecureRandom(), KyberParameters.kyber768); - break; - case "kyber1024": - PostQuantumParameters = new KyberKeyGenerationParameters(new Security.SecureRandom(), KyberParameters.kyber1024); - break; case "mlkem512": PostQuantumParameters = new KyberKeyGenerationParameters(new Security.SecureRandom(), KyberParameters.kyber512); break; @@ -236,15 +236,6 @@ private void InitializeParameters() case "mlkem1024": PostQuantumParameters = new KyberKeyGenerationParameters(new Security.SecureRandom(), KyberParameters.kyber1024); break; - case "dilithium2": - PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium2); - break; - case "dilithium3": - PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium3); - break; - case "dilithium5": - PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium5); - break; case "mldsa44": PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium2); break; @@ -254,15 +245,44 @@ private void InitializeParameters() case "mldsa87": PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium5); break; - case "sphincssha2128fsimple": + case "slh_dsa_sha2_128f": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_128f_simple); break; - case "sphincssha2192fsimple": + case "slh_dsa_sha2_192f": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_192f_simple); break; - case "sphincssha2256fsimple": + case "slh_dsa_sha2_256f": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_256f_simple); break; + case "slh_dsa_sha2_128s": + PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_128s_simple); + break; + case "slh_dsa_sha2_192s": + PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_192s_simple); + break; + case "slh_dsa_sha2_256s": + PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_256s_simple); + break; + case "slh_dsa_shake_128f": + PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.shake_128f_simple); + break; + case "slh_dsa_shake_192f": + PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.shake_192f_simple); + break; + case "slh_dsa_shake_256f": + PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.shake_256f_simple); + break; + case "slh_dsa_shake_128s": + PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.shake_128s_simple); + break; + case "slh_dsa_shake_192s": + PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.shake_192s_simple); + break; + case "slh_dsa_shake_256s": + PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.shake_256s_simple); + break; + default: + throw new Exception("Post-quantum algorithm not supported"); } } } diff --git a/crypto/src/crypto/parameters/HybridKeyParameters.cs b/crypto/src/crypto/parameters/HybridKeyParameters.cs index 424ec8326..93683108f 100644 --- a/crypto/src/crypto/parameters/HybridKeyParameters.cs +++ b/crypto/src/crypto/parameters/HybridKeyParameters.cs @@ -192,7 +192,7 @@ public HybridKeyParameters(AsymmetricKeyParameter classical, AsymmetricKeyParame } else if (PostQuantum is DilithiumKeyParameters) { - postQuantumCanonicalName = string.Concat("dilithium", (PostQuantum as DilithiumKeyParameters).Parameters.GetEngine(null).Mode.ToString()); + postQuantumCanonicalName = string.Concat("mldsa", (PostQuantum as DilithiumKeyParameters).Parameters.GetEngine(null).Mode.ToString()); } else if (PostQuantum is SphincsPlusKeyParameters) { diff --git a/crypto/src/pkcs/PrivateKeyInfoFactory.cs b/crypto/src/pkcs/PrivateKeyInfoFactory.cs index 46d7b0562..7f30c74c4 100644 --- a/crypto/src/pkcs/PrivateKeyInfoFactory.cs +++ b/crypto/src/pkcs/PrivateKeyInfoFactory.cs @@ -1,5 +1,4 @@ using System; - using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.CryptoPro; using Org.BouncyCastle.Asn1.EdEC; @@ -13,7 +12,14 @@ using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Pqc.Asn1; +using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; +using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; +using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; @@ -248,7 +254,94 @@ public static PrivateKeyInfo CreatePrivateKeyInfo(AsymmetricKeyParameter private if (privateKey is HybridKeyParameters) { - // FIXME(bence) + HybridKeyParameters key = (HybridKeyParameters)privateKey; + var names = key.CanonicalName.Split(Convert.ToChar("_")); + var classicalName = names[0]; + var postQuantumName = names[1]; + + byte[] classicalBytes = null; + switch (classicalName) + { + case "p256": + case "p384": + case "p521": + var ecPrivKey = key.Classical as ECPrivateKeyParameters; + ECPoint Q = new FixedPointCombMultiplier().Multiply(ecPrivKey.Parameters.G, ecPrivKey.D); + ECPublicKeyParameters ecPubKey = (ecPrivKey.PublicKeyParamSet == null) ? new ECPublicKeyParameters(ecPrivKey.AlgorithmName, Q, ecPrivKey.Parameters) : new ECPublicKeyParameters(ecPrivKey.AlgorithmName, Q, ecPrivKey.PublicKeyParamSet); + DerObjectIdentifier oid = null; + switch (classicalName) + { + case "p256": + oid = SecObjectIdentifiers.SecP256r1; + break; + case "p384": + oid = SecObjectIdentifiers.SecP384r1; + break; + case "p521": + oid = SecObjectIdentifiers.SecP521r1; + break; + } + var pubKeyDer = new DerBitString(ecPubKey.Q.GetEncoded()); + classicalBytes = new ECPrivateKeyStructure(SecNamedCurves.GetByOid(oid).N.BitLength, ecPrivKey.D, pubKeyDer, oid).GetDerEncoded(); + break; + case "x25519": + classicalBytes = (key.Classical as X25519PrivateKeyParameters).GetEncoded(); + break; + case "x448": + classicalBytes = (key.Classical as X448PrivateKeyParameters).GetEncoded(); + break; + case "ed25519": + classicalBytes = (key.Classical as Ed25519PrivateKeyParameters).GetEncoded(); + break; + case "ed448": + classicalBytes = (key.Classical as Ed448PrivateKeyParameters).GetEncoded(); + break; + } + + if (classicalBytes == null) + { + throw new Exception("Classical algorithm not supported"); + } + + byte[] postQuantumBytes = null; + switch (postQuantumName) + { + case "mlkem512": + case "mlkem768": + case "mlkem1024": + postQuantumBytes = (key.PostQuantum as KyberPrivateKeyParameters).GetEncoded(); + break; + case "mldsa44": + case "mldsa65": + case "mldsa87": + postQuantumBytes = (key.PostQuantum as DilithiumPrivateKeyParameters).GetEncoded(); + break; + case "slh_dsa_sha2_128f": + case "slh_dsa_sha2_192f": + case "slh_dsa_sha2_256f": + case "slh_dsa_sha2_128s": + case "slh_dsa_sha2_192s": + case "slh_dsa_sha2_256s": + case "slh_dsa_shake_128f": + case "slh_dsa_shake_192f": + case "slh_dsa_shake_256f": + case "slh_dsa_shake_128s": + case "slh_dsa_shake_192s": + case "slh_dsa_shake_256s": + postQuantumBytes = (key.PostQuantum as SphincsPlusPrivateKeyParameters).GetEncoded(); + break; + } + + if (postQuantumBytes == null) + { + throw new Exception("Post-quantum algorithm not supported"); + } + + byte[] combinedBytes = new byte[4 + classicalBytes.Length + postQuantumBytes.Length]; + Pack.UInt32_To_BE((uint)classicalBytes.Length, combinedBytes); + Array.Copy(classicalBytes, 0, combinedBytes, 4, classicalBytes.Length); + Array.Copy(postQuantumBytes, 0, combinedBytes, 4 + classicalBytes.Length, postQuantumBytes.Length); + return new PrivateKeyInfo(new AlgorithmIdentifier(key.AlgorithmOid), new DerOctetString(combinedBytes)); } throw new ArgumentException("Class provided is not convertible: " + Platform.GetTypeName(privateKey)); diff --git a/crypto/src/x509/SubjectPublicKeyInfoFactory.cs b/crypto/src/x509/SubjectPublicKeyInfoFactory.cs index a55d3403b..ffa110a67 100644 --- a/crypto/src/x509/SubjectPublicKeyInfoFactory.cs +++ b/crypto/src/x509/SubjectPublicKeyInfoFactory.cs @@ -11,8 +11,12 @@ using Org.BouncyCastle.crypto.parameters; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; +using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; +using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.X509 @@ -252,7 +256,77 @@ public static SubjectPublicKeyInfo CreateSubjectPublicKeyInfo( if (publicKey is HybridKeyParameters) { - // FIXME(bence) + HybridKeyParameters key = (HybridKeyParameters)publicKey; + var names = key.CanonicalName.Split(Convert.ToChar("_")); + var classicalName = names[0]; + var postQuantumName = names[1]; + + byte[] classicalBytes = null; + switch (classicalName) + { + case "p256": + case "p384": + case "p521": + classicalBytes = (key.Classical as ECPublicKeyParameters).Q.GetEncoded(); + break; + case "x25519": + classicalBytes = (key.Classical as X25519PublicKeyParameters).GetEncoded(); + break; + case "x448": + classicalBytes = (key.Classical as X448PublicKeyParameters).GetEncoded(); + break; + case "ed25519": + classicalBytes = (key.Classical as Ed25519PublicKeyParameters).GetEncoded(); + break; + case "ed448": + classicalBytes = (key.Classical as Ed448PublicKeyParameters).GetEncoded(); + break; + } + + if (classicalBytes == null) + { + throw new Exception("Classical algorithm not supported"); + } + + byte[] postQuantumBytes = null; + switch (postQuantumName) + { + case "mlkem512": + case "mlkem768": + case "mlkem1024": + postQuantumBytes = (key.PostQuantum as KyberPublicKeyParameters).GetEncoded(); + break; + case "mldsa44": + case "mldsa65": + case "mldsa87": + postQuantumBytes = (key.PostQuantum as DilithiumPublicKeyParameters).GetEncoded(); + break; + case "slh_dsa_sha2_128f": + case "slh_dsa_sha2_192f": + case "slh_dsa_sha2_256f": + case "slh_dsa_sha2_128s": + case "slh_dsa_sha2_192s": + case "slh_dsa_sha2_256s": + case "slh_dsa_shake_128f": + case "slh_dsa_shake_192f": + case "slh_dsa_shake_256f": + case "slh_dsa_shake_128s": + case "slh_dsa_shake_192s": + case "slh_dsa_shake_256s": + postQuantumBytes = (key.PostQuantum as SphincsPlusPublicKeyParameters).GetEncoded(); + break; + } + + if (postQuantumBytes == null) + { + throw new Exception("Post-quantum algorithm not supported"); + } + + byte[] combinedBytes = new byte[4 + classicalBytes.Length + postQuantumBytes.Length]; + Pack.UInt32_To_BE((uint)classicalBytes.Length, combinedBytes); + Array.Copy(classicalBytes, 0, combinedBytes, 4, classicalBytes.Length); + Array.Copy(postQuantumBytes, 0, combinedBytes, 4 + classicalBytes.Length, postQuantumBytes.Length); + return new SubjectPublicKeyInfo(new AlgorithmIdentifier(key.AlgorithmOid), combinedBytes); } throw new ArgumentException("Class provided no convertible: " + Platform.GetTypeName(publicKey)); From 1d3c77a8338a7c52bda469472551289e767d0112 Mon Sep 17 00:00:00 2001 From: Bence Mali Date: Tue, 10 Sep 2024 16:59:08 +0200 Subject: [PATCH 05/10] fixes and test updates --- .../crypto/generators/HybridKemGenerator.cs | 3 +- .../generators/HybridSignatureGenerator.cs | 14 +- .../HybridKeyGenerationParameters.cs | 90 +++++---- .../crypto/parameters/HybridKeyParameters.cs | 85 ++++---- crypto/src/pkcs/PrivateKeyInfoFactory.cs | 24 +-- crypto/src/security/PrivateKeyFactory.cs | 159 ++++++++++++--- crypto/src/security/PublicKeyFactory.cs | 140 ++++++++++--- .../src/x509/SubjectPublicKeyInfoFactory.cs | 24 +-- crypto/test/src/crypto/test/PQCHybridTest.cs | 185 ++++++++++++++++++ 9 files changed, 568 insertions(+), 156 deletions(-) create mode 100644 crypto/test/src/crypto/test/PQCHybridTest.cs diff --git a/crypto/src/crypto/generators/HybridKemGenerator.cs b/crypto/src/crypto/generators/HybridKemGenerator.cs index 6d7179509..b6ee4cdb3 100644 --- a/crypto/src/crypto/generators/HybridKemGenerator.cs +++ b/crypto/src/crypto/generators/HybridKemGenerator.cs @@ -114,7 +114,8 @@ public static ISecretWithEncapsulation Encapsulate(AsymmetricKeyParameter pubKey { var generator = new ECKeyPairGenerator("ECDH"); var pubInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(ecPublicKey); - var parameters = new ECKeyGenerationParameters(pubInfo.Algorithm.Algorithm, new SecureRandom()); + var domainParameters = new ECDomainParameters(ecPublicKey.Parameters.Curve, ecPublicKey.Parameters.G, ecPublicKey.Parameters.N); + var parameters = new ECKeyGenerationParameters(domainParameters, new SecureRandom()); generator.Init(parameters); var ephemeralKeypair = generator.GenerateKeyPair(); diff --git a/crypto/src/crypto/generators/HybridSignatureGenerator.cs b/crypto/src/crypto/generators/HybridSignatureGenerator.cs index 8341f4f45..97a4b8b03 100644 --- a/crypto/src/crypto/generators/HybridSignatureGenerator.cs +++ b/crypto/src/crypto/generators/HybridSignatureGenerator.cs @@ -14,10 +14,10 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Numerics; using System.Security; using System.Text; using System.Threading.Tasks; +using Org.BouncyCastle.Math; namespace Org.BouncyCastle.crypto.generators { @@ -124,7 +124,8 @@ public static byte[] GenerateSignature(AsymmetricKeyParameter privKey, byte[] me var signer = new ECDsaSigner(); signer.Init(true, ecPrivKey); var signature = signer.GenerateSignature(message); - classicalSignature = Arrays.Concatenate(signature[0].ToByteArrayUnsigned(), signature[1].ToByteArrayUnsigned()); + var encoding = new PlainDsaEncoding(); + classicalSignature = encoding.Encode(ecPrivKey.Parameters.N, signature[0], signature[1]); } else if (hybridPrivKey.Classical is Ed25519PrivateKeyParameters ed25519PrivKey) { @@ -186,20 +187,19 @@ public static bool VerifySignature(AsymmetricKeyParameter pubKey, byte[] message if (hybridPubKey.Classical is ECPublicKeyParameters ecPublicKey) { var domainParameters = ecPublicKey.Parameters; - var classicalSignatureLength = (domainParameters.N.BitLength / 8) * 2; + var classicalSignatureLength = BigIntegers.GetUnsignedByteLength(domainParameters.N) * 2; if (signature.Length <= classicalSignatureLength) { throw new Exception("Wrong size signature"); } - var classicalSignatureBytes = signature.Take(classicalSignatureLength).ToArray(); - var r = new Math.BigInteger(classicalSignatureBytes.Take(classicalSignatureLength / 2).ToArray()); - var s = new Math.BigInteger(classicalSignatureBytes.Skip(classicalSignatureLength / 2).ToArray()); + var encoding = new PlainDsaEncoding(); + var classicalSignature = encoding.Decode(domainParameters.N, signature.Take(classicalSignatureLength).ToArray()); var verifier = new ECDsaSigner(); verifier.Init(false, hybridPubKey.Classical); - if(!verifier.VerifySignature(message, r, s)) + if(!verifier.VerifySignature(message, classicalSignature[0], classicalSignature[1])) { throw new VerificationException("Signature verification failed"); } diff --git a/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs b/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs index a6c9fd5d6..94b2396ae 100644 --- a/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs +++ b/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs @@ -25,7 +25,7 @@ public class HybridKeyGenerationParameters { { "p256", SecObjectIdentifiers.SecP256r1 }, { "p384", SecObjectIdentifiers.SecP384r1 }, - { "p512", SecObjectIdentifiers.SecP521r1 }, + { "p521", SecObjectIdentifiers.SecP521r1 }, { "x25519", EdECObjectIdentifiers.id_X25519 }, { "x448", EdECObjectIdentifiers.id_X448 }, { "ed25519", EdECObjectIdentifiers.id_Ed25519 }, @@ -51,18 +51,18 @@ public class HybridKeyGenerationParameters { "mldsa44", NistObjectIdentifiers.IdHashMLDsa44WithSha512 }, { "mldsa65", NistObjectIdentifiers.IdHashMLDsa65WithSha512 }, { "mldsa87", NistObjectIdentifiers.IdHashMLDsa87WithSha512 }, - { "slh_dsa_sha2_128f", NistObjectIdentifiers.IdHashSlhDsasha2_128fWithSha256 }, - { "slh_dsa_sha2_192f", NistObjectIdentifiers.IdHashSlhDsasha2_192fWithSha512 }, - { "slh_dsa_sha2_256f", NistObjectIdentifiers.IdHashSlhDsasha2_256fWithSha512 }, - { "slh_dsa_sha2_128s", NistObjectIdentifiers.IdHashSlhDsaSha2_128sWithSha256 }, - { "slh_dsa_sha2_192s", NistObjectIdentifiers.IdHashSlhDsasha2_192sWithSha512 }, - { "slh_dsa_sha2_256s", NistObjectIdentifiers.IdHashSlhDsasha2_256sWithSha512 }, - { "slh_dsa_shake_128f", NistObjectIdentifiers.IdHashSlhDsashake_128fWithShake128 }, - { "slh_dsa_shake_192f", NistObjectIdentifiers.IdHashSlhDsashake_192fWithShake256 }, - { "slh_dsa_shake_256f", NistObjectIdentifiers.IdHashSlhDsashake_256fWithShake256 }, - { "slh_dsa_shake_128s", NistObjectIdentifiers.IdHashSlhDsashake_128sWithShake128 }, - { "slh_dsa_shake_192s", NistObjectIdentifiers.IdHashSlhDsashake_192sWithShake256 }, - { "slh_dsa_shake_256s", NistObjectIdentifiers.IdHashSlhDsashake_256sWithShake256 }, + { "slhdsasha2128f", NistObjectIdentifiers.IdHashSlhDsasha2_128fWithSha256 }, + { "slhdsasha2192f", NistObjectIdentifiers.IdHashSlhDsasha2_192fWithSha512 }, + { "slhdsasha2256f", NistObjectIdentifiers.IdHashSlhDsasha2_256fWithSha512 }, + { "slhdsasha2128s", NistObjectIdentifiers.IdHashSlhDsaSha2_128sWithSha256 }, + { "slhdsasha2192s", NistObjectIdentifiers.IdHashSlhDsasha2_192sWithSha512 }, + { "slhdsasha2256s", NistObjectIdentifiers.IdHashSlhDsasha2_256sWithSha512 }, + { "slhdsashake128f", NistObjectIdentifiers.IdHashSlhDsashake_128fWithShake128 }, + { "slhdsashake192f", NistObjectIdentifiers.IdHashSlhDsashake_192fWithShake256 }, + { "slhdsashake256f", NistObjectIdentifiers.IdHashSlhDsashake_256fWithShake256 }, + { "slhdsashake128s", NistObjectIdentifiers.IdHashSlhDsashake_128sWithShake128 }, + { "slhdsashake192s", NistObjectIdentifiers.IdHashSlhDsashake_192sWithShake256 }, + { "slhdsashake256s", NistObjectIdentifiers.IdHashSlhDsashake_256sWithShake256 }, }; public Dictionary postQuantumOidToName = new Dictionary() @@ -73,18 +73,18 @@ public class HybridKeyGenerationParameters { NistObjectIdentifiers.IdHashMLDsa44WithSha512 , "mldsa44" }, { NistObjectIdentifiers.IdHashMLDsa65WithSha512 , "mldsa65" }, { NistObjectIdentifiers.IdHashMLDsa87WithSha512 , "mldsa87" }, - { NistObjectIdentifiers.IdHashSlhDsasha2_128fWithSha256 , "slh_dsa_sha2_128f" }, - { NistObjectIdentifiers.IdHashSlhDsasha2_192fWithSha512 , "slh_dsa_sha2_192f" }, - { NistObjectIdentifiers.IdHashSlhDsasha2_256fWithSha512 , "slh_dsa_sha2_256f" }, - { NistObjectIdentifiers.IdHashSlhDsaSha2_128sWithSha256 , "slh_dsa_sha2_128s" }, - { NistObjectIdentifiers.IdHashSlhDsasha2_192sWithSha512 , "slh_dsa_sha2_192s" }, - { NistObjectIdentifiers.IdHashSlhDsasha2_256sWithSha512 , "slh_dsa_sha2_256s" }, - { NistObjectIdentifiers.IdHashSlhDsashake_128fWithShake128 , "slh_dsa_shake_128f" }, - { NistObjectIdentifiers.IdHashSlhDsashake_192fWithShake256 , "slh_dsa_shake_192f" }, - { NistObjectIdentifiers.IdHashSlhDsashake_256fWithShake256 , "slh_dsa_shake_256f" }, - { NistObjectIdentifiers.IdHashSlhDsashake_128sWithShake128 , "slh_dsa_shake_128s" }, - { NistObjectIdentifiers.IdHashSlhDsashake_192sWithShake256 , "slh_dsa_shake_192s" }, - { NistObjectIdentifiers.IdHashSlhDsashake_256sWithShake256 , "slh_dsa_shake_256s" }, + { NistObjectIdentifiers.IdHashSlhDsasha2_128fWithSha256 , "slhdsasha2128f" }, + { NistObjectIdentifiers.IdHashSlhDsasha2_192fWithSha512 , "slhdsasha2192f" }, + { NistObjectIdentifiers.IdHashSlhDsasha2_256fWithSha512 , "slhdsasha2256f" }, + { NistObjectIdentifiers.IdHashSlhDsaSha2_128sWithSha256 , "slhdsasha2128s" }, + { NistObjectIdentifiers.IdHashSlhDsasha2_192sWithSha512 , "slhdsasha2192s" }, + { NistObjectIdentifiers.IdHashSlhDsasha2_256sWithSha512 , "slhdsasha2256s" }, + { NistObjectIdentifiers.IdHashSlhDsashake_128fWithShake128 , "slhdsashake128f" }, + { NistObjectIdentifiers.IdHashSlhDsashake_192fWithShake256 , "slhdsashake192f" }, + { NistObjectIdentifiers.IdHashSlhDsashake_256fWithShake256 , "slhdsashake256f" }, + { NistObjectIdentifiers.IdHashSlhDsashake_128sWithShake128 , "slhdsashake128s" }, + { NistObjectIdentifiers.IdHashSlhDsashake_192sWithShake256 , "slhdsashake192s" }, + { NistObjectIdentifiers.IdHashSlhDsashake_256sWithShake256 , "slhdsashake256s" }, }; public DerObjectIdentifier ClassicalAlgorithm { get; set; } @@ -190,7 +190,7 @@ private void SetClassicals() { var names = HybridName.Split(Convert.ToChar("_")); ClassicalName = names[0]; - HybridName = names[1]; + PostQuantumName = names[1]; ClassicalAlgorithm = classicalNameToOid[ClassicalName]; PostQuantumAlgorithm = postQuantumNameToOid[PostQuantumName]; @@ -198,7 +198,7 @@ private void SetClassicals() private void SetHybrid() { - HybridName = string.Concat(ClassicalName, "_", HybridName); + HybridName = string.Concat(ClassicalName, "_", PostQuantumName); if (!HybridKeyParameters.HybridNameToOid.ContainsKey(HybridName)) { @@ -214,12 +214,20 @@ private void InitializeParameters() { case "p256": case "p384": - case "p512": + case "p521": + ClassicalParameters = new ECKeyGenerationParameters(ClassicalAlgorithm, new Security.SecureRandom()); + break; case "x25519": + ClassicalParameters = new X25519KeyGenerationParameters(new SecureRandom()); + break; case "x448": + ClassicalParameters = new X448KeyGenerationParameters(new SecureRandom()); + break; case "ed25519": + ClassicalParameters = new Ed25519KeyGenerationParameters(new SecureRandom()); + break; case "ed448": - ClassicalParameters = new ECKeyGenerationParameters(ClassicalAlgorithm, new Security.SecureRandom()); + ClassicalParameters = new Ed448KeyGenerationParameters(new SecureRandom()); break; default: throw new Exception("Classical algorithm not supported"); @@ -245,40 +253,40 @@ private void InitializeParameters() case "mldsa87": PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium5); break; - case "slh_dsa_sha2_128f": + case "slhdsasha2128f": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_128f_simple); break; - case "slh_dsa_sha2_192f": + case "slhdsasha2192f": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_192f_simple); break; - case "slh_dsa_sha2_256f": + case "slhdsasha2256f": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_256f_simple); break; - case "slh_dsa_sha2_128s": + case "slhdsasha2128s": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_128s_simple); break; - case "slh_dsa_sha2_192s": + case "slhdsasha2192s": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_192s_simple); break; - case "slh_dsa_sha2_256s": + case "slhdsasha2256s": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_256s_simple); break; - case "slh_dsa_shake_128f": + case "slhdsashake128f": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.shake_128f_simple); break; - case "slh_dsa_shake_192f": + case "slhdsashake192f": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.shake_192f_simple); break; - case "slh_dsa_shake_256f": + case "slhdsashake256f": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.shake_256f_simple); break; - case "slh_dsa_shake_128s": + case "slhdsashake128s": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.shake_128s_simple); break; - case "slh_dsa_shake_192s": + case "slhdsashake192s": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.shake_192s_simple); break; - case "slh_dsa_shake_256s": + case "slhdsashake256s": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.shake_256s_simple); break; default: diff --git a/crypto/src/crypto/parameters/HybridKeyParameters.cs b/crypto/src/crypto/parameters/HybridKeyParameters.cs index 93683108f..f8361c985 100644 --- a/crypto/src/crypto/parameters/HybridKeyParameters.cs +++ b/crypto/src/crypto/parameters/HybridKeyParameters.cs @@ -38,7 +38,6 @@ public class HybridKeyParameters //{ "rsa3072_dilithium2" , "1.3.9999.2.7.2" }, { "p384_dilithium3" , "1.3.9999.2.7.3" }, { "p521_dilithium5" , "1.3.9999.2.7.4" }, - { "p256_mldsa44" , "1.3.9999.7.1" }, //{ "rsa3072_mldsa44" , "1.3.9999.7.2" }, //{ "mldsa44_rsa2048" , "2.16.840.1.114027.80.8.1.2" }, { "ed25519_mldsa44" , "2.16.840.1.114027.80.8.1.3" }, @@ -50,22 +49,22 @@ public class HybridKeyParameters { "p521_mldsa87" , "1.3.9999.7.4" }, { "p384_mldsa87" , "2.16.840.1.114027.80.8.1.11" }, { "ed448_mldsa87" , "2.16.840.1.114027.80.8.1.13" }, - { "p256_sphincssha2128fsimple" , "1.3.9999.6.4.14" }, - //{ "rsa3072_sphincssha2128fsimple" , "1.3.9999.6.4.15" }, - { "p256_sphincssha2128ssimple" , "1.3.9999.6.4.17" }, - //{ "rsa3072_sphincssha2128ssimple" , "1.3.9999.6.4.18" }, - { "p384_sphincssha2192fsimple" , "1.3.9999.6.5.11" }, - { "p384_sphincssha2192ssimple" , "1.3.9999.6.5.13" }, - { "p521_sphincssha2256fsimple" , "1.3.9999.6.6.11" }, - { "p521_sphincssha2256ssimple" , "1.3.9999.6.6.13" }, - { "p256_sphincsshake128fsimple" , "1.3.9999.6.7.14" }, - //{ "rsa3072_sphincsshake128fsimple" , "1.3.9999.6.7.15" }, - { "p256_sphincsshake128ssimple" , "1.3.9999.6.7.17" }, - //{ "rsa3072_sphincsshake128ssimple" , "1.3.9999.6.7.18" }, - { "p384_sphincsshake192fsimple" , "1.3.9999.6.8.11" }, - { "p384_sphincsshake192ssimple" , "1.3.9999.6.8.13" }, - { "p521_sphincsshake256fsimple" , "1.3.9999.6.9.11" }, - { "p521_sphincsshake256ssimple" , "1.3.9999.6.9.13" }, + { "p256_slhdsasha2128f" , "1.3.9999.6.4.14" }, + //{ "rsa3072_slhdsasha2128f" , "1.3.9999.6.4.15" }, + { "p256_slhdsasha2128s" , "1.3.9999.6.4.17" }, + //{ "rsa3072_slhdsasha2128s" , "1.3.9999.6.4.18" }, + { "p384_slhdsasha2192f" , "1.3.9999.6.5.11" }, + { "p384_slhdsasha2192s" , "1.3.9999.6.5.13" }, + { "p521_slhdsasha2256f" , "1.3.9999.6.6.11" }, + { "p521_slhdsasha2256s" , "1.3.9999.6.6.13" }, + { "p256_slhdsashake128f" , "1.3.9999.6.7.14" }, + //{ "rsa3072_slhdsashake128f" , "1.3.9999.6.7.15" }, + { "p256_slhdsashake128s" , "1.3.9999.6.7.17" }, + //{ "rsa3072_slhdsashake128s" , "1.3.9999.6.7.18" }, + { "p384_slhdsashake192f" , "1.3.9999.6.8.11" }, + { "p384_slhdsashake192s" , "1.3.9999.6.8.13" }, + { "p521_slhdsashake256f" , "1.3.9999.6.9.11" }, + { "p521_slhdsashake256s" , "1.3.9999.6.9.13" }, }; public static readonly Dictionary HybridOidToName = new Dictionary() @@ -89,7 +88,6 @@ public class HybridKeyParameters //{ "1.3.9999.2.7.2" , "rsa3072_dilithium2" }, { "1.3.9999.2.7.3" , "p384_dilithium3" }, { "1.3.9999.2.7.4" , "p521_dilithium5" }, - { "1.3.9999.7.1" , "p256_mldsa44" }, //{ "1.3.9999.7.2" , "rsa3072_mldsa44" }, //{ "2.16.840.1.114027.80.8.1.2" , "mldsa44_rsa2048" }, { "2.16.840.1.114027.80.8.1.3" , "ed25519_mldsa44" }, @@ -101,22 +99,22 @@ public class HybridKeyParameters { "1.3.9999.7.4" , "p521_mldsa87" }, { "2.16.840.1.114027.80.8.1.11" , "p384_mldsa87" }, { "2.16.840.1.114027.80.8.1.13" , "ed448_mldsa87" }, - { "1.3.9999.6.4.14" , "p256_sphincssha2128fsimple" }, - //{ "1.3.9999.6.4.15" , "rsa3072_sphincssha2128fsimple" }, - { "1.3.9999.6.4.17" , "p256_sphincssha2128ssimple" }, - //{ "1.3.9999.6.4.18" , "rsa3072_sphincssha2128ssimple" }, - { "1.3.9999.6.5.11" , "p384_sphincssha2192fsimple" }, - { "1.3.9999.6.5.13" , "p384_sphincssha2192ssimple" }, - { "1.3.9999.6.6.11" , "p521_sphincssha2256fsimple" }, - { "1.3.9999.6.6.13" , "p521_sphincssha2256ssimple" }, - { "1.3.9999.6.7.14" , "p256_sphincsshake128fsimple" }, - //{ "1.3.9999.6.7.15" , "rsa3072_sphincsshake128fsimple" }, - { "1.3.9999.6.7.17" , "p256_sphincsshake128ssimple" }, - //{ "1.3.9999.6.7.18" , "rsa3072_sphincsshake128ssimple" }, - { "1.3.9999.6.8.11" , "p384_sphincsshake192fsimple" }, - { "1.3.9999.6.8.13" , "p384_sphincsshake192ssimple" }, - { "1.3.9999.6.9.11" , "p521_sphincsshake256fsimple" }, - { "1.3.9999.6.9.13" , "p521_sphincsshake256ssimple" }, + { "1.3.9999.6.4.14" , "p256_slhdsasha2128f" }, + //{ "1.3.9999.6.4.15" , "rsa3072_slhdsasha2128f" }, + { "1.3.9999.6.4.17" , "p256_slhdsasha2128s" }, + //{ "1.3.9999.6.4.18" , "rsa3072_slhdsasha2128s" }, + { "1.3.9999.6.5.11" , "p384_slhdsasha2192f" }, + { "1.3.9999.6.5.13" , "p384_slhdsasha2192s" }, + { "1.3.9999.6.6.11" , "p521_slhdsasha2256f" }, + { "1.3.9999.6.6.13" , "p521_slhdsasha2256s" }, + { "1.3.9999.6.7.14" , "p256_slhdsashake128f" }, + //{ "1.3.9999.6.7.15" , "rsa3072_slhdsashake128f" }, + { "1.3.9999.6.7.17" , "p256_slhdsashake128s" }, + //{ "1.3.9999.6.7.18" , "rsa3072_slhdsashake128s" }, + { "1.3.9999.6.8.11" , "p384_slhdsashake192f" }, + { "1.3.9999.6.8.13" , "p384_slhdsashake192s" }, + { "1.3.9999.6.9.11" , "p521_slhdsashake256f" }, + { "1.3.9999.6.9.13" , "p521_slhdsashake256s" }, }; public readonly DerObjectIdentifier AlgorithmOid; @@ -188,15 +186,26 @@ public HybridKeyParameters(AsymmetricKeyParameter classical, AsymmetricKeyParame if (PostQuantum is KyberKeyParameters) { - postQuantumCanonicalName = (PostQuantum as KyberKeyParameters).Parameters.Name; + postQuantumCanonicalName = (PostQuantum as KyberKeyParameters).Parameters.Name.Replace("kyber", "mlkem"); } else if (PostQuantum is DilithiumKeyParameters) { - postQuantumCanonicalName = string.Concat("mldsa", (PostQuantum as DilithiumKeyParameters).Parameters.GetEngine(null).Mode.ToString()); + switch ((PostQuantum as DilithiumKeyParameters).Parameters.GetEngine(null).Mode) + { + case 2: + postQuantumCanonicalName = string.Concat("mldsa", $"{44}"); + break; + case 3: + postQuantumCanonicalName = string.Concat("mldsa", $"{65}"); + break; + case 5: + postQuantumCanonicalName = string.Concat("mldsa", $"{87}"); + break; + } } else if (PostQuantum is SphincsPlusKeyParameters) { - postQuantumCanonicalName = (PostQuantum as SphincsPlusKeyParameters).Parameters.Name.Replace("-", ""); + postQuantumCanonicalName = String.Concat("slhdsa", (PostQuantum as SphincsPlusKeyParameters).Parameters.Name.Replace("-", "").Replace("simple", "")); } if (postQuantumCanonicalName != null && classicalCanonicalName != null) @@ -213,7 +222,7 @@ public HybridKeyParameters(AsymmetricKeyParameter classical, AsymmetricKeyParame { if(!HybridNameToOid.TryGetValue(CanonicalName, out objectId)) { - throw new Exception("Object identifier for hybrid combination not found"); + throw new Exception($"Object identifier for {CanonicalName} not found"); } } diff --git a/crypto/src/pkcs/PrivateKeyInfoFactory.cs b/crypto/src/pkcs/PrivateKeyInfoFactory.cs index 7f30c74c4..3e73b4db8 100644 --- a/crypto/src/pkcs/PrivateKeyInfoFactory.cs +++ b/crypto/src/pkcs/PrivateKeyInfoFactory.cs @@ -316,18 +316,18 @@ public static PrivateKeyInfo CreatePrivateKeyInfo(AsymmetricKeyParameter private case "mldsa87": postQuantumBytes = (key.PostQuantum as DilithiumPrivateKeyParameters).GetEncoded(); break; - case "slh_dsa_sha2_128f": - case "slh_dsa_sha2_192f": - case "slh_dsa_sha2_256f": - case "slh_dsa_sha2_128s": - case "slh_dsa_sha2_192s": - case "slh_dsa_sha2_256s": - case "slh_dsa_shake_128f": - case "slh_dsa_shake_192f": - case "slh_dsa_shake_256f": - case "slh_dsa_shake_128s": - case "slh_dsa_shake_192s": - case "slh_dsa_shake_256s": + case "slhdsasha2128f": + case "slhdsasha2192f": + case "slhdsasha2256f": + case "slhdsasha2128s": + case "slhdsasha2192s": + case "slhdsasha2256s": + case "slhdsashake128f": + case "slhdsashake192f": + case "slhdsashake256f": + case "slhdsashake128s": + case "slhdsashake192s": + case "slhdsashake256s": postQuantumBytes = (key.PostQuantum as SphincsPlusPrivateKeyParameters).GetEncoded(); break; } diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs index 8f98995f5..beba014ed 100644 --- a/crypto/src/security/PrivateKeyFactory.cs +++ b/crypto/src/security/PrivateKeyFactory.cs @@ -16,6 +16,7 @@ using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Math; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; @@ -356,28 +357,76 @@ public static AsymmetricKeyParameter CreateKey( var classicalName = names[0]; var postQuantumName = names[1]; + var hybridBytes = GetRawKey(keyInfo).ToArray(); + var keyParameters = new HybridKeyGenerationParameters(new SecureRandom(), classicalName, postQuantumName); + AsymmetricKeyParameter classicalKey = null; int classicalKeySize = 0; if (keyParameters.ClassicalParameters is ECKeyGenerationParameters ecKeyParameters) { - classicalKeySize = ecKeyParameters.DomainParameters.Curve.FieldElementEncodingLength; + if (hybridBytes.Length <= 4) + { + throw new Exception("Encoded hybrid private key has wrong size"); + } + try + { + classicalKeySize = Convert.ToInt32(Pack.BE_To_UInt32(hybridBytes.Take(4).ToArray())); + } + catch + { + throw new Exception("Invalid encoding"); + } + + if (hybridBytes.Length <= 4 + classicalKeySize) + { + throw new Exception("Encoded hybrid private key has wrong size"); + } + + var obj = Asn1Object.FromByteArray(hybridBytes.Skip(4).Take(classicalKeySize).ToArray()); + + var structure = ECPrivateKeyStructure.GetInstance(obj); + classicalKey = new ECPrivateKeyParameters(structure.GetKey(), ecKeyParameters.DomainParameters); } else if (keyParameters.ClassicalParameters is X25519KeyGenerationParameters) { classicalKeySize = X25519PrivateKeyParameters.KeySize; + if (hybridBytes.Length <= 4 + classicalKeySize) + { + throw new Exception("Encoded hybrid private key has wrong size"); + } + + classicalKey = new X25519PrivateKeyParameters(hybridBytes.Skip(4).Take(classicalKeySize).ToArray()); } else if (keyParameters.ClassicalParameters is Ed25519KeyGenerationParameters) { classicalKeySize = Ed25519PrivateKeyParameters.KeySize; + if (hybridBytes.Length <= 4 + classicalKeySize) + { + throw new Exception("Encoded hybrid private key has wrong size"); + } + + classicalKey = new Ed25519PrivateKeyParameters(hybridBytes.Skip(4).Take(classicalKeySize).ToArray()); } else if (keyParameters.ClassicalParameters is X448KeyGenerationParameters) { classicalKeySize = X448PrivateKeyParameters.KeySize; + if (hybridBytes.Length <= 4 + classicalKeySize) + { + throw new Exception("Encoded hybrid private key has wrong size"); + } + + classicalKey = new X448PrivateKeyParameters(hybridBytes.Skip(4).Take(classicalKeySize).ToArray()); } else if (keyParameters.ClassicalParameters is Ed448KeyGenerationParameters) { classicalKeySize = Ed448PrivateKeyParameters.KeySize; + if (hybridBytes.Length <= 4 + classicalKeySize) + { + throw new Exception("Encoded hybrid private key has wrong size"); + } + + classicalKey = new Ed448PrivateKeyParameters(hybridBytes.Skip(4).Take(classicalKeySize).ToArray()); } else if (keyParameters.ClassicalParameters is RsaKeyGenerationParameters) { @@ -385,82 +434,146 @@ public static AsymmetricKeyParameter CreateKey( throw new Exception("Rsa hybrid keys not supported"); } - if (classicalKeySize == 0) + if (classicalKey == null) { throw new Exception("Classical keytype not supported"); } - int postQuantumKeySize = 0; + hybridBytes = hybridBytes.Skip(4 + classicalKeySize).ToArray(); + + AsymmetricKeyParameter postQuantumKey = null; if (keyParameters.PostQuantumParameters is KyberKeyGenerationParameters kyberParameters) { + int postQuantumKeySize = 0; + KyberParameters parameters; switch (kyberParameters.Parameters.Name) { case "kyber512": postQuantumKeySize = 1632; + parameters = KyberParameters.kyber512; break; case "kyber768": postQuantumKeySize = 2400; + parameters = KyberParameters.kyber768; break; case "kyber1024": postQuantumKeySize = 3168; + parameters = KyberParameters.kyber1024; break; + default: + throw new Exception("Post-quantum keytype not supported"); + } + + if (hybridBytes.Length != postQuantumKeySize) + { + throw new Exception("Encoded hybrid private key has wrong size"); } + + postQuantumKey = new KyberPrivateKeyParameters(parameters, hybridBytes); } else if (keyParameters.PostQuantumParameters is DilithiumKeyGenerationParameters dilithiumParameters) { + int postQuantumKeySize = 0; + DilithiumParameters parameters; switch (dilithiumParameters.Parameters.Name) { case "dilithium2": postQuantumKeySize = 2560; + parameters = DilithiumParameters.Dilithium2; break; case "dilithium3": postQuantumKeySize = 4032; + parameters = DilithiumParameters.Dilithium3; break; case "dilithium5": postQuantumKeySize = 4896; + parameters = DilithiumParameters.Dilithium5; break; + default: + throw new Exception("Post-quantum keytype not supported"); + } + + if (hybridBytes.Length != postQuantumKeySize) + { + throw new Exception("Encoded hybrid private key has wrong size"); } + + var publicParams = new DilithiumPublicKeyParameters(parameters, hybridBytes); + + postQuantumKey = new DilithiumPrivateKeyParameters(parameters, hybridBytes, publicParams); } else if (keyParameters.PostQuantumParameters is SphincsPlusKeyGenerationParameters sphincsParameters) { + int postQuantumKeySize = 0; + SphincsPlusParameters parameters; switch (sphincsParameters.Parameters.Name) { case "sha2-128f-simple": postQuantumKeySize = 64; + parameters = SphincsPlusParameters.sha2_128f_simple; + break; + case "sha2-128s-simple": + postQuantumKeySize = 64; + parameters = SphincsPlusParameters.sha2_128s_simple; break; case "sha2-192f-simple": postQuantumKeySize = 96; + parameters = SphincsPlusParameters.sha2_192f_simple; + break; + case "sha2-192s-simple": + postQuantumKeySize = 96; + parameters = SphincsPlusParameters.sha2_192s_simple; break; case "sha2-256f-simple": postQuantumKeySize = 128; + parameters = SphincsPlusParameters.sha2_256f_simple; + break; + case "sha2-256s-simple": + postQuantumKeySize = 128; + parameters = SphincsPlusParameters.sha2_256s_simple; + break; + case "shake-128f-simple": + postQuantumKeySize = 64; + parameters = SphincsPlusParameters.shake_128f_simple; + break; + case "shake-128s-simple": + postQuantumKeySize = 64; + parameters = SphincsPlusParameters.shake_128s_simple; + break; + case "shake-192f-simple": + postQuantumKeySize = 96; + parameters = SphincsPlusParameters.shake_192f_simple; break; + case "shake-192s-simple": + postQuantumKeySize = 96; + parameters = SphincsPlusParameters.shake_192s_simple; + break; + case "shake-256f-simple": + postQuantumKeySize = 128; + parameters = SphincsPlusParameters.shake_256f_simple; + break; + case "shake-256s-simple": + postQuantumKeySize = 128; + parameters = SphincsPlusParameters.shake_256s_simple; + break; + default: + throw new Exception("Post-quantum keytype not supported"); } - } - if (postQuantumKeySize == 0) - { - throw new Exception("Post-quantum keytype not supported"); - } + if (hybridBytes.Length != postQuantumKeySize) + { + throw new Exception("Encoded hybrid private key has wrong size"); + } - // expected format: - // first 4 bytes are length of the classical private key - // then comes the classical private key - // finally the post-quantum private key - var hybridBytes = keyInfo.PrivateKey.GetOctets(); + postQuantumKey = new SphincsPlusPrivateKeyParameters(parameters, hybridBytes); + } - // deliberately ignoring classical keysize encoding - if (hybridBytes.Length != 4 + classicalKeySize + postQuantumKeySize) + if (postQuantumKey == null) { - throw new Exception("Encoded hybrid private key has wrong size"); + throw new Exception("Post-quantum keytype not supported"); } - var classicalBytes = hybridBytes.Skip(4).Take(classicalKeySize).ToArray(); - var postQuantumBytes = hybridBytes.Skip(4).Skip(classicalKeySize).ToArray(); - - var classicalKeyParameter = PrivateKeyFactory.CreateKey(classicalBytes); - var postQuantumKeyParameter = PqcPrivateKeyFactory.CreateKey(postQuantumBytes); - - return new HybridKeyParameters(classicalKeyParameter, postQuantumKeyParameter); + return new HybridKeyParameters(classicalKey, postQuantumKey); } else { diff --git a/crypto/src/security/PublicKeyFactory.cs b/crypto/src/security/PublicKeyFactory.cs index cabcae758..920aa4d67 100644 --- a/crypto/src/security/PublicKeyFactory.cs +++ b/crypto/src/security/PublicKeyFactory.cs @@ -9,6 +9,7 @@ using Org.BouncyCastle.Asn1.Oiw; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.Rosstandart; +using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.crypto.parameters; @@ -285,29 +286,62 @@ public static AsymmetricKeyParameter CreateKey( var classicalName = names[0]; var postQuantumName = names[1]; + var hybridBytes = keyInfo.PublicKey.GetBytes(); + var keyParameters = new HybridKeyGenerationParameters(new SecureRandom(), classicalName, postQuantumName); + AsymmetricKeyParameter classicalKey = null; int classicalKeySize = 0; if (keyParameters.ClassicalParameters is ECKeyGenerationParameters ecKeyParameters) { // public key is uncompressed ec point classicalKeySize = (ecKeyParameters.DomainParameters.Curve.FieldElementEncodingLength * 2) + 1; + if (hybridBytes.Length <= 4 + classicalKeySize) + { + throw new Exception("Encoded hybrid public key has wrong size"); + } + + classicalKey = new ECPublicKeyParameters(new X9ECPoint(ecKeyParameters.DomainParameters.Curve, new DerOctetString(hybridBytes.Skip(4).Take(classicalKeySize).ToArray())).Point, ecKeyParameters.DomainParameters); } else if (keyParameters.ClassicalParameters is X25519KeyGenerationParameters) { classicalKeySize = X25519PublicKeyParameters.KeySize; + if (hybridBytes.Length <= 4 + classicalKeySize) + { + throw new Exception("Encoded hybrid public key has wrong size"); + } + + classicalKey = new X25519PublicKeyParameters(hybridBytes.Skip(4).Take(classicalKeySize).ToArray()); } else if (keyParameters.ClassicalParameters is Ed25519KeyGenerationParameters) { classicalKeySize = Ed25519PublicKeyParameters.KeySize; + if (hybridBytes.Length <= 4 + classicalKeySize) + { + throw new Exception("Encoded hybrid public key has wrong size"); + } + + classicalKey = new Ed25519PublicKeyParameters(hybridBytes.Skip(4).Take(classicalKeySize).ToArray()); } else if (keyParameters.ClassicalParameters is X448KeyGenerationParameters) { classicalKeySize = X448PublicKeyParameters.KeySize; + if (hybridBytes.Length <= 4 + classicalKeySize) + { + throw new Exception("Encoded hybrid public key has wrong size"); + } + + classicalKey = new X448PublicKeyParameters(hybridBytes.Skip(4).Take(classicalKeySize).ToArray()); } else if (keyParameters.ClassicalParameters is Ed448KeyGenerationParameters) { classicalKeySize = Ed448PublicKeyParameters.KeySize; + if (hybridBytes.Length <= 4 + classicalKeySize) + { + throw new Exception("Encoded hybrid public key has wrong size"); + } + + classicalKey = new Ed448PublicKeyParameters(hybridBytes.Skip(4).Take(classicalKeySize).ToArray()); } else if (keyParameters.ClassicalParameters is RsaKeyGenerationParameters) { @@ -315,82 +349,144 @@ public static AsymmetricKeyParameter CreateKey( throw new Exception("Rsa hybrid keys not supported"); } - if (classicalKeySize == 0) + if (classicalKey == null) { throw new Exception("Classical keytype not supported"); } - int postQuantumKeySize = 0; + hybridBytes = hybridBytes.Skip(4 + classicalKeySize).ToArray(); + + AsymmetricKeyParameter postQuantumKey = null; if (keyParameters.PostQuantumParameters is KyberKeyGenerationParameters kyberParameters) { + int postQuantumKeySize = 0; + KyberParameters parameters; switch (kyberParameters.Parameters.Name) { case "kyber512": postQuantumKeySize = 800; + parameters = KyberParameters.kyber512; break; case "kyber768": postQuantumKeySize = 1184; + parameters = KyberParameters.kyber768; break; case "kyber1024": postQuantumKeySize = 1568; + parameters = KyberParameters.kyber1024; break; + default: + throw new Exception("Post-quantum keytype not supported"); + } + + if (hybridBytes.Length != postQuantumKeySize) + { + throw new Exception("Encoded hybrid public key has wrong size"); } + + postQuantumKey = new KyberPublicKeyParameters(parameters, hybridBytes); } else if (keyParameters.PostQuantumParameters is DilithiumKeyGenerationParameters dilithiumParameters) { + int postQuantumKeySize = 0; + DilithiumParameters parameters; switch (dilithiumParameters.Parameters.Name) { case "dilithium2": postQuantumKeySize = 1312; + parameters = DilithiumParameters.Dilithium2; break; case "dilithium3": postQuantumKeySize = 1952; + parameters = DilithiumParameters.Dilithium3; break; case "dilithium5": postQuantumKeySize = 2592; + parameters = DilithiumParameters.Dilithium5; break; + default: + throw new Exception("Post-quantum keytype not supported"); + } + + if (hybridBytes.Length != postQuantumKeySize) + { + throw new Exception("Encoded hybrid public key has wrong size"); } + + postQuantumKey = new DilithiumPublicKeyParameters(parameters, hybridBytes); } else if (keyParameters.PostQuantumParameters is SphincsPlusKeyGenerationParameters sphincsParameters) { + int postQuantumKeySize = 0; + SphincsPlusParameters parameters; switch (sphincsParameters.Parameters.Name) { case "sha2-128f-simple": postQuantumKeySize = 32; + parameters = SphincsPlusParameters.sha2_128f_simple; + break; + case "sha2-128s-simple": + postQuantumKeySize = 32; + parameters = SphincsPlusParameters.sha2_128s_simple; break; case "sha2-192f-simple": postQuantumKeySize = 48; + parameters = SphincsPlusParameters.sha2_192f_simple; + break; + case "sha2-192s-simple": + postQuantumKeySize = 48; + parameters = SphincsPlusParameters.sha2_192s_simple; break; case "sha2-256f-simple": postQuantumKeySize = 64; + parameters = SphincsPlusParameters.sha2_256f_simple; + break; + case "sha2-256s-simple": + postQuantumKeySize = 64; + parameters = SphincsPlusParameters.sha2_256s_simple; + break; + case "shake-128f-simple": + postQuantumKeySize = 32; + parameters = SphincsPlusParameters.shake_128f_simple; + break; + case "shake-128s-simple": + postQuantumKeySize = 32; + parameters = SphincsPlusParameters.shake_128s_simple; + break; + case "shake-192f-simple": + postQuantumKeySize = 48; + parameters = SphincsPlusParameters.shake_192f_simple; + break; + case "shake-192s-simple": + postQuantumKeySize = 48; + parameters = SphincsPlusParameters.shake_192s_simple; + break; + case "shake-256f-simple": + postQuantumKeySize = 64; + parameters = SphincsPlusParameters.shake_256f_simple; break; + case "shake-256s-simple": + postQuantumKeySize = 64; + parameters = SphincsPlusParameters.shake_256s_simple; + break; + default: + throw new Exception("Post-quantum keytype not supported"); } - } - if (postQuantumKeySize == 0) - { - throw new Exception("Post-quantum keytype not supported"); - } + if (hybridBytes.Length != postQuantumKeySize) + { + throw new Exception("Encoded hybrid public key has wrong size"); + } - // expected format: - // first 4 bytes are length of the classical public key - // then comes the classical public key - // finally the post-quantum public key - var hybridBytes = keyInfo.PublicKey.GetBytes(); + postQuantumKey = new SphincsPlusPublicKeyParameters(parameters, hybridBytes); + } - // deliberately ignoring classical keysize encoding - if (hybridBytes.Length != 4 + classicalKeySize + postQuantumKeySize) + if (postQuantumKey == null) { - throw new Exception("Encoded hybrid public key has wrong size"); + throw new Exception("Post-quantum keytype not supported"); } - var classicalBytes = hybridBytes.Skip(4).Take(classicalKeySize).ToArray(); - var postQuantumBytes = hybridBytes.Skip(4).Skip(classicalKeySize).ToArray(); - - var classicalKeyParameter = PublicKeyFactory.CreateKey(classicalBytes); - var postQuantumKeyParameter = PqcPublicKeyFactory.CreateKey(postQuantumBytes); - - return new HybridKeyParameters(classicalKeyParameter, postQuantumKeyParameter); + return new HybridKeyParameters(classicalKey, postQuantumKey); } else { diff --git a/crypto/src/x509/SubjectPublicKeyInfoFactory.cs b/crypto/src/x509/SubjectPublicKeyInfoFactory.cs index ffa110a67..6a24a5993 100644 --- a/crypto/src/x509/SubjectPublicKeyInfoFactory.cs +++ b/crypto/src/x509/SubjectPublicKeyInfoFactory.cs @@ -301,18 +301,18 @@ public static SubjectPublicKeyInfo CreateSubjectPublicKeyInfo( case "mldsa87": postQuantumBytes = (key.PostQuantum as DilithiumPublicKeyParameters).GetEncoded(); break; - case "slh_dsa_sha2_128f": - case "slh_dsa_sha2_192f": - case "slh_dsa_sha2_256f": - case "slh_dsa_sha2_128s": - case "slh_dsa_sha2_192s": - case "slh_dsa_sha2_256s": - case "slh_dsa_shake_128f": - case "slh_dsa_shake_192f": - case "slh_dsa_shake_256f": - case "slh_dsa_shake_128s": - case "slh_dsa_shake_192s": - case "slh_dsa_shake_256s": + case "slhdsasha2128f": + case "slhdsasha2192f": + case "slhdsasha2256f": + case "slhdsasha2128s": + case "slhdsasha2192s": + case "slhdsasha2256s": + case "slhdsashake128f": + case "slhdsashake192f": + case "slhdsashake256f": + case "slhdsashake128s": + case "slhdsashake192s": + case "slhdsashake256s": postQuantumBytes = (key.PostQuantum as SphincsPlusPublicKeyParameters).GetEncoded(); break; } diff --git a/crypto/test/src/crypto/test/PQCHybridTest.cs b/crypto/test/src/crypto/test/PQCHybridTest.cs new file mode 100644 index 000000000..636ee2dae --- /dev/null +++ b/crypto/test/src/crypto/test/PQCHybridTest.cs @@ -0,0 +1,185 @@ +using NUnit.Framework; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.crypto.generators; +using Org.BouncyCastle.crypto.parameters; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Org.BouncyCastle.src.crypto.test +{ + [TestFixture] + public class PQCHybridTest + { + private static readonly SecureRandom Random = new SecureRandom(); + + private static List postQuantumKems = new List() + { + "mlkem512", + "mlkem768", + "mlkem1024", + }; + + private static List classicalEcdh = new List() + { + "p256", + "p384", + "p521", + "x25519", + "x448", + }; + + private static List postQuantumSignatures = new List() + { + "mldsa44", + "mldsa65", + "mldsa87", + "slhdsasha2128f", + "slhdsasha2192f", + "slhdsasha2256f", + "slhdsasha2128s", + "slhdsasha2192s", + "slhdsasha2256s", + "slhdsashake128f", + "slhdsashake192f", + "slhdsashake256f", + "slhdsashake128s", + "slhdsashake192s", + "slhdsashake256s", + }; + + private static List classicalSignatures = new List() + { + "p256", + "p384", + "p521", + "x25519", + "x448", + }; + + [Test] + public void TestKems() + { + foreach (var postQuantum in postQuantumKems) + { + foreach (var classical in classicalEcdh) + { + var hybridName = $"{classical}_{postQuantum}"; + + // generate keypair + var keypair = GenerateKeypair(hybridName, true); + + if (keypair == null) continue; + + // encode/decode + + var pubKey = PublicTryEnDecode(keypair.Public); + + var privKey = PrivateTryEnDecode(keypair.Private); + + // encapsulate + var encapsulation = HybridKemGenerator.Encapsulate(pubKey); + + // decapsulate + var secret = HybridKemGenerator.Decapsulate(privKey, encapsulation.GetEncapsulation()); + Assert.AreEqual(encapsulation.GetSecret(), secret); + + Console.WriteLine($"success: {hybridName}"); + } + } + } + + [Test] + public void TestSignatures() + { + foreach (var postQuantum in postQuantumSignatures) + { + foreach (var classical in classicalSignatures) + { + var hybridName = $"{classical}_{postQuantum}"; + + // generate keypair + var keypair = GenerateKeypair(hybridName, false); + + if (keypair == null) continue; + + // encode/decode + + var pubKey = PublicTryEnDecode(keypair.Public); + + var privKey = PrivateTryEnDecode(keypair.Private); + + // random message + byte[] message = new byte[32]; + Random.NextBytes(message); + + // sign + var signature = HybridSignatureGenerator.GenerateSignature(privKey, message); + + // verify + Assert.IsTrue(HybridSignatureGenerator.VerifySignature(pubKey, message, signature)); + + Console.WriteLine($"success: {hybridName}"); + } + } + } + + private static AsymmetricCipherKeyPair GenerateKeypair(string hybridName, bool isKem) + { + HybridKeyGenerationParameters hybridParameters; + try + { + hybridParameters = new HybridKeyGenerationParameters(Random, hybridName); + } + catch (ArgumentException ex) when (ex.Message.Equals("Unsupported hybrid combination")) + { + return null; + } + if (isKem) + { + var generator = new HybridKemGenerator(); + generator.Init(hybridParameters); + return generator.GenerateKeyPair(); + } + else + { + var generator = new HybridSignatureGenerator(); + generator.Init(hybridParameters); + return generator.GenerateKeyPair(); + } + } + + private static AsymmetricKeyParameter PublicTryEnDecode(AsymmetricKeyParameter pubKey) + { + // encode + var pubKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubKey); + var pubKeyBytes = pubKeyInfo.GetEncoded(); + + // decode + var pubKey1 = PublicKeyFactory.CreateKey(pubKeyInfo); + var pubKey2 = PublicKeyFactory.CreateKey(pubKeyBytes); + + return pubKey2; + } + + private static AsymmetricKeyParameter PrivateTryEnDecode(AsymmetricKeyParameter privKey) + { + // encode + var privKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privKey); + var privKeyInfoBytes = privKeyInfo.GetEncoded(); + + // decode + var privKey1 = PrivateKeyFactory.CreateKey(privKeyInfo); + var privKey2 = PrivateKeyFactory.CreateKey(privKeyInfoBytes); + + return privKey2; + } + } +} From 767e79307b0e4882993e51e439b39faf698d27a1 Mon Sep 17 00:00:00 2001 From: Bence Mali Date: Wed, 11 Sep 2024 15:05:27 +0200 Subject: [PATCH 06/10] kyber to mlkem rename --- .../crypto/generators/HybridKemGenerator.cs | 16 +++++----- .../HybridKeyGenerationParameters.cs | 8 ++--- .../crypto/parameters/HybridKeyParameters.cs | 32 +++++++++---------- crypto/src/pkcs/PrivateKeyInfoFactory.cs | 4 +-- crypto/src/security/PrivateKeyFactory.cs | 22 ++++++------- crypto/src/security/PublicKeyFactory.cs | 22 ++++++------- .../src/x509/SubjectPublicKeyInfoFactory.cs | 3 +- 7 files changed, 52 insertions(+), 55 deletions(-) diff --git a/crypto/src/crypto/generators/HybridKemGenerator.cs b/crypto/src/crypto/generators/HybridKemGenerator.cs index b6ee4cdb3..8ca4b8d2a 100644 --- a/crypto/src/crypto/generators/HybridKemGenerator.cs +++ b/crypto/src/crypto/generators/HybridKemGenerator.cs @@ -7,7 +7,7 @@ using Org.BouncyCastle.Crypto.Agreement; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; +using Org.BouncyCastle.Pqc.Crypto.MLKem; using Org.BouncyCastle.Pqc.Crypto.Utilities; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; @@ -84,9 +84,9 @@ public AsymmetricCipherKeyPair GenerateKeyPair() } AsymmetricCipherKeyPair postQuantumKeypair = null; - if (parameters.PostQuantumParameters is KyberKeyGenerationParameters) + if (parameters.PostQuantumParameters is MLKemKeyGenerationParameters) { - var generator = new KyberKeyPairGenerator(); + var generator = new MLKemKeyPairGenerator(); generator.Init(parameters.PostQuantumParameters); postQuantumKeypair = generator.GenerateKeyPair(); } @@ -168,9 +168,9 @@ public static ISecretWithEncapsulation Encapsulate(AsymmetricKeyParameter pubKey byte[] postQuantumCiphertext = null; byte[] postQuantumSharedSecret = null; - if (hybridPubKey.PostQuantum is KyberPublicKeyParameters) + if (hybridPubKey.PostQuantum is MLKemPublicKeyParameters) { - var encapsulation = new KyberKemGenerator(new SecureRandom()).GenerateEncapsulated(hybridPubKey.PostQuantum); + var encapsulation = new MLKemGenerator(new SecureRandom()).GenerateEncapsulated(hybridPubKey.PostQuantum); postQuantumCiphertext = encapsulation.GetEncapsulation(); postQuantumSharedSecret = encapsulation.GetSecret(); } @@ -267,14 +267,14 @@ public static byte[] Decapsulate(AsymmetricKeyParameter privKey, byte[] cipherte } byte[] postQuantumSharedSecret = null; - if (hybridPrivKey.PostQuantum is KyberPrivateKeyParameters postQuantum) + if (hybridPrivKey.PostQuantum is MLKemPrivateKeyParameters postQuantum) { - var extractor = new KyberKemExtractor(postQuantum); + var extractor = new MLKemExtractor(postQuantum); if (ciphertext.Length != extractor.EncapsulationLength) { throw new Exception("Wrong size post-quantum ciphertext"); } - postQuantumSharedSecret = new KyberKemExtractor(postQuantum).ExtractSecret(ciphertext); + postQuantumSharedSecret = extractor.ExtractSecret(ciphertext); } if (postQuantumSharedSecret == null) diff --git a/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs b/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs index 94b2396ae..02cee4c35 100644 --- a/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs +++ b/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs @@ -7,7 +7,7 @@ using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; -using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; +using Org.BouncyCastle.Pqc.Crypto.MLKem; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Security; using System; @@ -236,13 +236,13 @@ private void InitializeParameters() switch (PostQuantumName) { case "mlkem512": - PostQuantumParameters = new KyberKeyGenerationParameters(new Security.SecureRandom(), KyberParameters.kyber512); + PostQuantumParameters = new MLKemKeyGenerationParameters(new Security.SecureRandom(), MLKemParameters.ML_KEM_512); break; case "mlkem768": - PostQuantumParameters = new KyberKeyGenerationParameters(new Security.SecureRandom(), KyberParameters.kyber768); + PostQuantumParameters = new MLKemKeyGenerationParameters(new Security.SecureRandom(), MLKemParameters.ML_KEM_768); break; case "mlkem1024": - PostQuantumParameters = new KyberKeyGenerationParameters(new Security.SecureRandom(), KyberParameters.kyber1024); + PostQuantumParameters = new MLKemKeyGenerationParameters(new Security.SecureRandom(), MLKemParameters.ML_KEM_1024); break; case "mldsa44": PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium2); diff --git a/crypto/src/crypto/parameters/HybridKeyParameters.cs b/crypto/src/crypto/parameters/HybridKeyParameters.cs index f8361c985..fb9bab830 100644 --- a/crypto/src/crypto/parameters/HybridKeyParameters.cs +++ b/crypto/src/crypto/parameters/HybridKeyParameters.cs @@ -4,7 +4,7 @@ using Org.BouncyCastle.Math.EC.Custom.Sec; using Org.BouncyCastle.Math.EC.Rfc7748; using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; -using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; +using Org.BouncyCastle.Pqc.Crypto.MLKem; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using System; using System.Collections.Generic; @@ -19,13 +19,6 @@ public class HybridKeyParameters { public static readonly Dictionary HybridNameToOid = new Dictionary() { - { "p256_kyber512" , "1.3.9999.99.72" }, - { "x25519_kyber512" , "1.3.9999.99.49" }, - { "p384_kyber768" , "1.3.9999.99.73" }, - { "x448_kyber768" , "1.3.9999.99.50" }, - { "x25519_kyber768" , "1.3.9999.99.51" }, - { "p256_kyber768" , "1.3.9999.99.52" }, - { "p521_kyber1024" , "1.3.9999.99.74" }, { "p256_mlkem512" , "1.3.6.1.4.1.22554.5.7.1" }, { "x25519_mlkem512" , "1.3.6.1.4.1.22554.5.8.1" }, { "p384_mlkem768" , "1.3.9999.99.75" }, @@ -69,13 +62,6 @@ public class HybridKeyParameters public static readonly Dictionary HybridOidToName = new Dictionary() { - { "1.3.9999.99.72" , "p256_kyber512" }, - { "1.3.9999.99.49" , "x25519_kyber512" }, - { "1.3.9999.99.73" , "p384_kyber768" }, - { "1.3.9999.99.50" , "x448_kyber768" }, - { "1.3.9999.99.51" , "x25519_kyber768" }, - { "1.3.9999.99.52" , "p256_kyber768" }, - { "1.3.9999.99.74" , "p521_kyber1024" }, { "1.3.6.1.4.1.22554.5.7.1" , "p256_mlkem512" }, { "1.3.6.1.4.1.22554.5.8.1" , "x25519_mlkem512" }, { "1.3.9999.99.75" , "p384_mlkem768" }, @@ -184,9 +170,21 @@ public HybridKeyParameters(AsymmetricKeyParameter classical, AsymmetricKeyParame string postQuantumCanonicalName = null; - if (PostQuantum is KyberKeyParameters) + if (PostQuantum is MLKemKeyParameters) { - postQuantumCanonicalName = (PostQuantum as KyberKeyParameters).Parameters.Name.Replace("kyber", "mlkem"); + var name = (PostQuantum as MLKemKeyParameters).Parameters.Name; + switch (name) + { + case "ML-KEM-512": + postQuantumCanonicalName = "mlkem512"; + break; + case "ML-KEM-768": + postQuantumCanonicalName = "mlkem768"; + break; + case "ML-KEM-1024": + postQuantumCanonicalName = "mlkem1024"; + break; + } } else if (PostQuantum is DilithiumKeyParameters) { diff --git a/crypto/src/pkcs/PrivateKeyInfoFactory.cs b/crypto/src/pkcs/PrivateKeyInfoFactory.cs index dbc05291b..de362a247 100644 --- a/crypto/src/pkcs/PrivateKeyInfoFactory.cs +++ b/crypto/src/pkcs/PrivateKeyInfoFactory.cs @@ -18,7 +18,7 @@ using Org.BouncyCastle.Math.EC.Multiplier; using Org.BouncyCastle.Pqc.Asn1; using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; -using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; +using Org.BouncyCastle.Pqc.Crypto.MLKem; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; @@ -320,7 +320,7 @@ public static PrivateKeyInfo CreatePrivateKeyInfo(AsymmetricKeyParameter private case "mlkem512": case "mlkem768": case "mlkem1024": - postQuantumBytes = (key.PostQuantum as KyberPrivateKeyParameters).GetEncoded(); + postQuantumBytes = (key.PostQuantum as MLKemPrivateKeyParameters).GetEncoded(); break; case "mldsa44": case "mldsa65": diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs index af72048f4..eb4bdbf9e 100644 --- a/crypto/src/security/PrivateKeyFactory.cs +++ b/crypto/src/security/PrivateKeyFactory.cs @@ -21,7 +21,7 @@ using Org.BouncyCastle.Math; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; -using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; +using Org.BouncyCastle.Pqc.Crypto.MLKem; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Pqc.Crypto.Utilities; @@ -460,23 +460,23 @@ public static AsymmetricKeyParameter CreateKey( hybridBytes = hybridBytes.Skip(4 + classicalKeySize).ToArray(); AsymmetricKeyParameter postQuantumKey = null; - if (keyParameters.PostQuantumParameters is KyberKeyGenerationParameters kyberParameters) + if (keyParameters.PostQuantumParameters is MLKemKeyGenerationParameters mlkemParameters) { int postQuantumKeySize = 0; - KyberParameters parameters; - switch (kyberParameters.Parameters.Name) + MLKemParameters parameters; + switch (mlkemParameters.Parameters.Name) { - case "kyber512": + case "ML-KEM-512": postQuantumKeySize = 1632; - parameters = KyberParameters.kyber512; + parameters = MLKemParameters.ML_KEM_512; break; - case "kyber768": + case "ML-KEM-768": postQuantumKeySize = 2400; - parameters = KyberParameters.kyber768; + parameters = MLKemParameters.ML_KEM_768; break; - case "kyber1024": + case "ML-KEM-1024": postQuantumKeySize = 3168; - parameters = KyberParameters.kyber1024; + parameters = MLKemParameters.ML_KEM_1024; break; default: throw new Exception("Post-quantum keytype not supported"); @@ -487,7 +487,7 @@ public static AsymmetricKeyParameter CreateKey( throw new Exception("Encoded hybrid private key has wrong size"); } - postQuantumKey = new KyberPrivateKeyParameters(parameters, hybridBytes); + postQuantumKey = new MLKemPrivateKeyParameters(parameters, hybridBytes); } else if (keyParameters.PostQuantumParameters is DilithiumKeyGenerationParameters dilithiumParameters) { diff --git a/crypto/src/security/PublicKeyFactory.cs b/crypto/src/security/PublicKeyFactory.cs index 5fbd1af8b..8b146bc47 100644 --- a/crypto/src/security/PublicKeyFactory.cs +++ b/crypto/src/security/PublicKeyFactory.cs @@ -20,7 +20,7 @@ using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; -using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; +using Org.BouncyCastle.Pqc.Crypto.MLKem; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Pqc.Crypto.Utilities; @@ -363,23 +363,23 @@ public static AsymmetricKeyParameter CreateKey( hybridBytes = hybridBytes.Skip(4 + classicalKeySize).ToArray(); AsymmetricKeyParameter postQuantumKey = null; - if (keyParameters.PostQuantumParameters is KyberKeyGenerationParameters kyberParameters) + if (keyParameters.PostQuantumParameters is MLKemKeyGenerationParameters mlkemParameters) { int postQuantumKeySize = 0; - KyberParameters parameters; - switch (kyberParameters.Parameters.Name) + MLKemParameters parameters; + switch (mlkemParameters.Parameters.Name) { - case "kyber512": + case "ML-KEM-512": postQuantumKeySize = 800; - parameters = KyberParameters.kyber512; + parameters = MLKemParameters.ML_KEM_512; break; - case "kyber768": + case "ML-KEM-768": postQuantumKeySize = 1184; - parameters = KyberParameters.kyber768; + parameters = MLKemParameters.ML_KEM_768; break; - case "kyber1024": + case "ML-KEM-1024": postQuantumKeySize = 1568; - parameters = KyberParameters.kyber1024; + parameters = MLKemParameters.ML_KEM_1024; break; default: throw new Exception("Post-quantum keytype not supported"); @@ -390,7 +390,7 @@ public static AsymmetricKeyParameter CreateKey( throw new Exception("Encoded hybrid public key has wrong size"); } - postQuantumKey = new KyberPublicKeyParameters(parameters, hybridBytes); + postQuantumKey = new MLKemPublicKeyParameters(parameters, hybridBytes); } else if (keyParameters.PostQuantumParameters is DilithiumKeyGenerationParameters dilithiumParameters) { diff --git a/crypto/src/x509/SubjectPublicKeyInfoFactory.cs b/crypto/src/x509/SubjectPublicKeyInfoFactory.cs index dcbc3f6ef..93fc800e6 100644 --- a/crypto/src/x509/SubjectPublicKeyInfoFactory.cs +++ b/crypto/src/x509/SubjectPublicKeyInfoFactory.cs @@ -16,7 +16,6 @@ using Org.BouncyCastle.Math.EC; using Org.BouncyCastle.Pqc.Crypto.MLKem; using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; -using Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Utilities; @@ -302,7 +301,7 @@ public static SubjectPublicKeyInfo CreateSubjectPublicKeyInfo( case "mlkem512": case "mlkem768": case "mlkem1024": - postQuantumBytes = (key.PostQuantum as KyberPublicKeyParameters).GetEncoded(); + postQuantumBytes = (key.PostQuantum as MLKemPublicKeyParameters).GetEncoded(); break; case "mldsa44": case "mldsa65": From 6aec7d568e66f21ef2c1249e544cb24c34c7b4e0 Mon Sep 17 00:00:00 2001 From: Bence Mali Date: Thu, 12 Sep 2024 16:25:21 +0200 Subject: [PATCH 07/10] KEM interop test with oqs-provider --- .../HybridKeyGenerationParameters.cs | 12 +-- .../crypto/parameters/HybridKeyParameters.cs | 88 +---------------- .../src/crypto/parameters/HybridParameters.cs | 97 +++++++++++++++++++ crypto/src/security/PrivateKeyFactory.cs | 4 +- crypto/src/security/PublicKeyFactory.cs | 4 +- .../kem/p256_mlkem512/ciphertext.base64.txt | 1 + .../oqsprovider/kem/p256_mlkem512/privkey.pem | 40 ++++++++ .../oqsprovider/kem/p256_mlkem512/pubkey.pem | 21 ++++ .../p256_mlkem512/shared_secret.base64.txt | 1 + .../kem/p256_mlkem768/ciphertext.base64.txt | 1 + .../oqsprovider/kem/p256_mlkem768/privkey.pem | 56 +++++++++++ .../oqsprovider/kem/p256_mlkem768/pubkey.pem | 29 ++++++ .../p256_mlkem768/shared_secret.base64.txt | 1 + .../kem/p384_mlkem1024/ciphertext.base64.txt | 1 + .../kem/p384_mlkem1024/privkey.pem | 73 ++++++++++++++ .../oqsprovider/kem/p384_mlkem1024/pubkey.pem | 38 ++++++++ .../p384_mlkem1024/shared_secret.base64.txt | 1 + .../kem/p384_mlkem768/ciphertext.base64.txt | 1 + .../oqsprovider/kem/p384_mlkem768/privkey.pem | 57 +++++++++++ .../oqsprovider/kem/p384_mlkem768/pubkey.pem | 30 ++++++ .../p384_mlkem768/shared_secret.base64.txt | 1 + .../kem/p521_mlkem1024/ciphertext.base64.txt | 1 + .../kem/p521_mlkem1024/privkey.pem | 74 ++++++++++++++ .../oqsprovider/kem/p521_mlkem1024/pubkey.pem | 38 ++++++++ .../p521_mlkem1024/shared_secret.base64.txt | 1 + .../kem/x25519_mlkem512/ciphertext.base64.txt | 1 + .../kem/x25519_mlkem512/privkey.pem | 38 ++++++++ .../kem/x25519_mlkem512/pubkey.pem | 20 ++++ .../x25519_mlkem512/shared_secret.base64.txt | 1 + .../kem/x25519_mlkem768/ciphertext.base64.txt | 1 + .../kem/x25519_mlkem768/privkey.pem | 54 +++++++++++ .../kem/x25519_mlkem768/pubkey.pem | 28 ++++++ .../x25519_mlkem768/shared_secret.base64.txt | 1 + .../kem/x448_mlkem768/ciphertext.base64.txt | 1 + .../oqsprovider/kem/x448_mlkem768/privkey.pem | 54 +++++++++++ .../oqsprovider/kem/x448_mlkem768/pubkey.pem | 29 ++++++ .../x448_mlkem768/shared_secret.base64.txt | 1 + crypto/test/src/crypto/test/PQCHybridTest.cs | 82 ++++++++++++++++ crypto/test/src/util/test/SimpleTest.cs | 10 ++ 39 files changed, 895 insertions(+), 97 deletions(-) create mode 100644 crypto/src/crypto/parameters/HybridParameters.cs create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/ciphertext.base64.txt create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/privkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/pubkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/shared_secret.base64.txt create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/ciphertext.base64.txt create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/privkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/pubkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/shared_secret.base64.txt create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/ciphertext.base64.txt create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/privkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/pubkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/shared_secret.base64.txt create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/ciphertext.base64.txt create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/privkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/pubkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/shared_secret.base64.txt create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/ciphertext.base64.txt create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/privkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/pubkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/shared_secret.base64.txt create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/ciphertext.base64.txt create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/privkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/pubkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/shared_secret.base64.txt create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/ciphertext.base64.txt create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/privkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/pubkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/shared_secret.base64.txt create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/ciphertext.base64.txt create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/privkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/pubkey.pem create mode 100644 crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/shared_secret.base64.txt diff --git a/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs b/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs index 02cee4c35..4270672f9 100644 --- a/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs +++ b/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs @@ -155,12 +155,12 @@ public HybridKeyGenerationParameters(SecureRandom random, string classicalAlgori public HybridKeyGenerationParameters(SecureRandom random, DerObjectIdentifier hybridAlgorithm) : base(random, 256) { - if (!HybridKeyParameters.HybridOidToName.ContainsKey(hybridAlgorithm.Id)) + if (!HybridParameters.HybridOidToName.ContainsKey(hybridAlgorithm.Id)) { throw new ArgumentException("Unsupported hybrid combination"); } - HybridName = HybridKeyParameters.HybridOidToName[hybridAlgorithm.Id]; + HybridName = HybridParameters.HybridOidToName[hybridAlgorithm.Id]; HybridAlgorithm = hybridAlgorithm; SetClassicals(); @@ -173,13 +173,13 @@ public HybridKeyGenerationParameters(SecureRandom random, string hybridAlgorithm { hybridAlgorithm = hybridAlgorithm.ToLowerInvariant(); - if (!HybridKeyParameters.HybridNameToOid.ContainsKey(hybridAlgorithm)) + if (!HybridParameters.HybridNameToOid.ContainsKey(hybridAlgorithm)) { throw new ArgumentException("Unsupported hybrid combination"); } HybridName = hybridAlgorithm; - HybridAlgorithm = new DerObjectIdentifier(HybridKeyParameters.HybridNameToOid[hybridAlgorithm]); + HybridAlgorithm = new DerObjectIdentifier(HybridParameters.HybridNameToOid[hybridAlgorithm]); SetClassicals(); @@ -200,12 +200,12 @@ private void SetHybrid() { HybridName = string.Concat(ClassicalName, "_", PostQuantumName); - if (!HybridKeyParameters.HybridNameToOid.ContainsKey(HybridName)) + if (!HybridParameters.HybridNameToOid.ContainsKey(HybridName)) { throw new Exception("Unsupported hybrid combination"); } - HybridAlgorithm = new DerObjectIdentifier(HybridKeyParameters.HybridNameToOid[HybridName]); + HybridAlgorithm = new DerObjectIdentifier(HybridParameters.HybridNameToOid[HybridName]); } private void InitializeParameters() diff --git a/crypto/src/crypto/parameters/HybridKeyParameters.cs b/crypto/src/crypto/parameters/HybridKeyParameters.cs index fb9bab830..c85582d11 100644 --- a/crypto/src/crypto/parameters/HybridKeyParameters.cs +++ b/crypto/src/crypto/parameters/HybridKeyParameters.cs @@ -17,92 +17,6 @@ namespace Org.BouncyCastle.crypto.parameters public class HybridKeyParameters : AsymmetricKeyParameter { - public static readonly Dictionary HybridNameToOid = new Dictionary() - { - { "p256_mlkem512" , "1.3.6.1.4.1.22554.5.7.1" }, - { "x25519_mlkem512" , "1.3.6.1.4.1.22554.5.8.1" }, - { "p384_mlkem768" , "1.3.9999.99.75" }, - { "x448_mlkem768" , "1.3.9999.99.53" }, - { "x25519_mlkem768" , "1.3.9999.99.54" }, - { "p256_mlkem768" , "1.3.9999.99.55" }, - { "p521_mlkem1024" , "1.3.9999.99.76" }, - { "p384_mlkem1024" , "1.3.6.1.4.1.42235.6" }, - { "p256_dilithium2" , "1.3.9999.2.7.1" }, - //{ "rsa3072_dilithium2" , "1.3.9999.2.7.2" }, - { "p384_dilithium3" , "1.3.9999.2.7.3" }, - { "p521_dilithium5" , "1.3.9999.2.7.4" }, - //{ "rsa3072_mldsa44" , "1.3.9999.7.2" }, - //{ "mldsa44_rsa2048" , "2.16.840.1.114027.80.8.1.2" }, - { "ed25519_mldsa44" , "2.16.840.1.114027.80.8.1.3" }, - { "p256_mldsa44" , "2.16.840.1.114027.80.8.1.4" }, - { "p384_mldsa65" , "1.3.9999.7.3" }, - //{ "mldsa65_rsa3072" , "2.16.840.1.114027.80.8.1.7" }, - { "p256_mldsa65" , "2.16.840.1.114027.80.8.1.8" }, - { "ed25519_mldsa65" , "2.16.840.1.114027.80.8.1.10" }, - { "p521_mldsa87" , "1.3.9999.7.4" }, - { "p384_mldsa87" , "2.16.840.1.114027.80.8.1.11" }, - { "ed448_mldsa87" , "2.16.840.1.114027.80.8.1.13" }, - { "p256_slhdsasha2128f" , "1.3.9999.6.4.14" }, - //{ "rsa3072_slhdsasha2128f" , "1.3.9999.6.4.15" }, - { "p256_slhdsasha2128s" , "1.3.9999.6.4.17" }, - //{ "rsa3072_slhdsasha2128s" , "1.3.9999.6.4.18" }, - { "p384_slhdsasha2192f" , "1.3.9999.6.5.11" }, - { "p384_slhdsasha2192s" , "1.3.9999.6.5.13" }, - { "p521_slhdsasha2256f" , "1.3.9999.6.6.11" }, - { "p521_slhdsasha2256s" , "1.3.9999.6.6.13" }, - { "p256_slhdsashake128f" , "1.3.9999.6.7.14" }, - //{ "rsa3072_slhdsashake128f" , "1.3.9999.6.7.15" }, - { "p256_slhdsashake128s" , "1.3.9999.6.7.17" }, - //{ "rsa3072_slhdsashake128s" , "1.3.9999.6.7.18" }, - { "p384_slhdsashake192f" , "1.3.9999.6.8.11" }, - { "p384_slhdsashake192s" , "1.3.9999.6.8.13" }, - { "p521_slhdsashake256f" , "1.3.9999.6.9.11" }, - { "p521_slhdsashake256s" , "1.3.9999.6.9.13" }, - }; - - public static readonly Dictionary HybridOidToName = new Dictionary() - { - { "1.3.6.1.4.1.22554.5.7.1" , "p256_mlkem512" }, - { "1.3.6.1.4.1.22554.5.8.1" , "x25519_mlkem512" }, - { "1.3.9999.99.75" , "p384_mlkem768" }, - { "1.3.9999.99.53" , "x448_mlkem768" }, - { "1.3.9999.99.54" , "x25519_mlkem768" }, - { "1.3.9999.99.55" , "p256_mlkem768" }, - { "1.3.9999.99.76" , "p521_mlkem1024" }, - { "1.3.6.1.4.1.42235.6" , "p384_mlkem1024" }, - { "1.3.9999.2.7.1" , "p256_dilithium2" }, - //{ "1.3.9999.2.7.2" , "rsa3072_dilithium2" }, - { "1.3.9999.2.7.3" , "p384_dilithium3" }, - { "1.3.9999.2.7.4" , "p521_dilithium5" }, - //{ "1.3.9999.7.2" , "rsa3072_mldsa44" }, - //{ "2.16.840.1.114027.80.8.1.2" , "mldsa44_rsa2048" }, - { "2.16.840.1.114027.80.8.1.3" , "ed25519_mldsa44" }, - { "2.16.840.1.114027.80.8.1.4" , "p256_mldsa44" }, - { "1.3.9999.7.3" , "p384_mldsa65" }, - //{ "2.16.840.1.114027.80.8.1.7" , "mldsa65_rsa3072" }, - { "2.16.840.1.114027.80.8.1.8" , "p256_mldsa65" }, - { "2.16.840.1.114027.80.8.1.10" , "ed25519_mldsa65" }, - { "1.3.9999.7.4" , "p521_mldsa87" }, - { "2.16.840.1.114027.80.8.1.11" , "p384_mldsa87" }, - { "2.16.840.1.114027.80.8.1.13" , "ed448_mldsa87" }, - { "1.3.9999.6.4.14" , "p256_slhdsasha2128f" }, - //{ "1.3.9999.6.4.15" , "rsa3072_slhdsasha2128f" }, - { "1.3.9999.6.4.17" , "p256_slhdsasha2128s" }, - //{ "1.3.9999.6.4.18" , "rsa3072_slhdsasha2128s" }, - { "1.3.9999.6.5.11" , "p384_slhdsasha2192f" }, - { "1.3.9999.6.5.13" , "p384_slhdsasha2192s" }, - { "1.3.9999.6.6.11" , "p521_slhdsasha2256f" }, - { "1.3.9999.6.6.13" , "p521_slhdsasha2256s" }, - { "1.3.9999.6.7.14" , "p256_slhdsashake128f" }, - //{ "1.3.9999.6.7.15" , "rsa3072_slhdsashake128f" }, - { "1.3.9999.6.7.17" , "p256_slhdsashake128s" }, - //{ "1.3.9999.6.7.18" , "rsa3072_slhdsashake128s" }, - { "1.3.9999.6.8.11" , "p384_slhdsashake192f" }, - { "1.3.9999.6.8.13" , "p384_slhdsashake192s" }, - { "1.3.9999.6.9.11" , "p521_slhdsashake256f" }, - { "1.3.9999.6.9.13" , "p521_slhdsashake256s" }, - }; - public readonly DerObjectIdentifier AlgorithmOid; public AsymmetricKeyParameter Classical { get; private set; } @@ -218,7 +132,7 @@ public HybridKeyParameters(AsymmetricKeyParameter classical, AsymmetricKeyParame string objectId = null; if (CanonicalName != null) { - if(!HybridNameToOid.TryGetValue(CanonicalName, out objectId)) + if(!HybridParameters.HybridNameToOid.TryGetValue(CanonicalName, out objectId)) { throw new Exception($"Object identifier for {CanonicalName} not found"); } diff --git a/crypto/src/crypto/parameters/HybridParameters.cs b/crypto/src/crypto/parameters/HybridParameters.cs new file mode 100644 index 000000000..61cd5a4cc --- /dev/null +++ b/crypto/src/crypto/parameters/HybridParameters.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Org.BouncyCastle.crypto.parameters +{ + public class HybridParameters + { + public static readonly Dictionary HybridNameToOid = new Dictionary() + { + { "p256_mlkem512" , "1.3.6.1.4.1.22554.5.7.1" }, + { "x25519_mlkem512" , "1.3.6.1.4.1.22554.5.8.1" }, + { "p384_mlkem768" , "1.3.9999.99.75" }, + { "x448_mlkem768" , "1.3.9999.99.53" }, + { "x25519_mlkem768" , "1.3.9999.99.54" }, + { "p256_mlkem768" , "1.3.9999.99.55" }, + { "p521_mlkem1024" , "1.3.9999.99.76" }, + { "p384_mlkem1024" , "1.3.6.1.4.1.42235.6" }, + { "p256_dilithium2" , "1.3.9999.2.7.1" }, + { "rsa3072_dilithium2" , "1.3.9999.2.7.2" }, + { "p384_dilithium3" , "1.3.9999.2.7.3" }, + { "p521_dilithium5" , "1.3.9999.2.7.4" }, + { "rsa3072_mldsa44" , "1.3.9999.7.2" }, + { "mldsa44_rsa2048" , "2.16.840.1.114027.80.8.1.2" }, + { "ed25519_mldsa44" , "2.16.840.1.114027.80.8.1.3" }, + { "p256_mldsa44" , "2.16.840.1.114027.80.8.1.4" }, + { "p384_mldsa65" , "1.3.9999.7.3" }, + { "mldsa65_rsa3072" , "2.16.840.1.114027.80.8.1.7" }, + { "p256_mldsa65" , "2.16.840.1.114027.80.8.1.8" }, + { "ed25519_mldsa65" , "2.16.840.1.114027.80.8.1.10" }, + { "p521_mldsa87" , "1.3.9999.7.4" }, + { "p384_mldsa87" , "2.16.840.1.114027.80.8.1.11" }, + { "ed448_mldsa87" , "2.16.840.1.114027.80.8.1.13" }, + { "p256_slhdsasha2128f" , "1.3.9999.6.4.14" }, + { "rsa3072_slhdsasha2128f" , "1.3.9999.6.4.15" }, + { "p256_slhdsasha2128s" , "1.3.9999.6.4.17" }, + { "rsa3072_slhdsasha2128s" , "1.3.9999.6.4.18" }, + { "p384_slhdsasha2192f" , "1.3.9999.6.5.11" }, + { "p384_slhdsasha2192s" , "1.3.9999.6.5.13" }, + { "p521_slhdsasha2256f" , "1.3.9999.6.6.11" }, + { "p521_slhdsasha2256s" , "1.3.9999.6.6.13" }, + { "p256_slhdsashake128f" , "1.3.9999.6.7.14" }, + { "rsa3072_slhdsashake128f" , "1.3.9999.6.7.15" }, + { "p256_slhdsashake128s" , "1.3.9999.6.7.17" }, + { "rsa3072_slhdsashake128s" , "1.3.9999.6.7.18" }, + { "p384_slhdsashake192f" , "1.3.9999.6.8.11" }, + { "p384_slhdsashake192s" , "1.3.9999.6.8.13" }, + { "p521_slhdsashake256f" , "1.3.9999.6.9.11" }, + { "p521_slhdsashake256s" , "1.3.9999.6.9.13" }, + }; + + public static readonly Dictionary HybridOidToName = new Dictionary() + { + { "1.3.6.1.4.1.22554.5.7.1" , "p256_mlkem512" }, + { "1.3.6.1.4.1.22554.5.8.1" , "x25519_mlkem512" }, + { "1.3.9999.99.75" , "p384_mlkem768" }, + { "1.3.9999.99.53" , "x448_mlkem768" }, + { "1.3.9999.99.54" , "x25519_mlkem768" }, + { "1.3.9999.99.55" , "p256_mlkem768" }, + { "1.3.9999.99.76" , "p521_mlkem1024" }, + { "1.3.6.1.4.1.42235.6" , "p384_mlkem1024" }, + { "1.3.9999.2.7.1" , "p256_dilithium2" }, + { "1.3.9999.2.7.2" , "rsa3072_dilithium2" }, + { "1.3.9999.2.7.3" , "p384_dilithium3" }, + { "1.3.9999.2.7.4" , "p521_dilithium5" }, + { "1.3.9999.7.2" , "rsa3072_mldsa44" }, + { "2.16.840.1.114027.80.8.1.2" , "mldsa44_rsa2048" }, + { "2.16.840.1.114027.80.8.1.3" , "ed25519_mldsa44" }, + { "2.16.840.1.114027.80.8.1.4" , "p256_mldsa44" }, + { "1.3.9999.7.3" , "p384_mldsa65" }, + { "2.16.840.1.114027.80.8.1.7" , "mldsa65_rsa3072" }, + { "2.16.840.1.114027.80.8.1.8" , "p256_mldsa65" }, + { "2.16.840.1.114027.80.8.1.10" , "ed25519_mldsa65" }, + { "1.3.9999.7.4" , "p521_mldsa87" }, + { "2.16.840.1.114027.80.8.1.11" , "p384_mldsa87" }, + { "2.16.840.1.114027.80.8.1.13" , "ed448_mldsa87" }, + { "1.3.9999.6.4.14" , "p256_slhdsasha2128f" }, + { "1.3.9999.6.4.15" , "rsa3072_slhdsasha2128f" }, + { "1.3.9999.6.4.17" , "p256_slhdsasha2128s" }, + { "1.3.9999.6.4.18" , "rsa3072_slhdsasha2128s" }, + { "1.3.9999.6.5.11" , "p384_slhdsasha2192f" }, + { "1.3.9999.6.5.13" , "p384_slhdsasha2192s" }, + { "1.3.9999.6.6.11" , "p521_slhdsasha2256f" }, + { "1.3.9999.6.6.13" , "p521_slhdsasha2256s" }, + { "1.3.9999.6.7.14" , "p256_slhdsashake128f" }, + { "1.3.9999.6.7.15" , "rsa3072_slhdsashake128f" }, + { "1.3.9999.6.7.17" , "p256_slhdsashake128s" }, + { "1.3.9999.6.7.18" , "rsa3072_slhdsashake128s" }, + { "1.3.9999.6.8.11" , "p384_slhdsashake192f" }, + { "1.3.9999.6.8.13" , "p384_slhdsashake192s" }, + { "1.3.9999.6.9.11" , "p521_slhdsashake256f" }, + { "1.3.9999.6.9.13" , "p521_slhdsashake256s" }, + }; + } +} diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs index eb4bdbf9e..34cf5720a 100644 --- a/crypto/src/security/PrivateKeyFactory.cs +++ b/crypto/src/security/PrivateKeyFactory.cs @@ -368,9 +368,9 @@ public static AsymmetricKeyParameter CreateKey( return new MLDsaPrivateKeyParameters(parameters, encoding.GetOctets()); } - else if (HybridKeyParameters.HybridOidToName.ContainsKey(algOid.Id)) + else if (HybridParameters.HybridOidToName.ContainsKey(algOid.Id)) { - var hybridName = HybridKeyParameters.HybridOidToName[algOid.Id]; + var hybridName = HybridParameters.HybridOidToName[algOid.Id]; var names = hybridName.Split(Convert.ToChar("_")); var classicalName = names[0]; var postQuantumName = names[1]; diff --git a/crypto/src/security/PublicKeyFactory.cs b/crypto/src/security/PublicKeyFactory.cs index 8b146bc47..ee2433b23 100644 --- a/crypto/src/security/PublicKeyFactory.cs +++ b/crypto/src/security/PublicKeyFactory.cs @@ -285,9 +285,9 @@ public static AsymmetricKeyParameter CreateKey( { return GetMLDsaPublicKey(MLDsaParameters.FromOid(algOid), keyInfo.PublicKey); } - else if (HybridKeyParameters.HybridOidToName.ContainsKey(algOid.Id)) + else if (HybridParameters.HybridOidToName.ContainsKey(algOid.Id)) { - var hybridName = HybridKeyParameters.HybridOidToName[algOid.Id]; + var hybridName = HybridParameters.HybridOidToName[algOid.Id]; var names = hybridName.Split(Convert.ToChar("_")); var classicalName = names[0]; var postQuantumName = names[1]; diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/ciphertext.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/ciphertext.base64.txt new file mode 100644 index 000000000..2d67adbe0 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/ciphertext.base64.txt @@ -0,0 +1 @@ +BCngs+6hwWNgFvlG4cYKpCd1ctdP5NI8ZTBNq0MWN3D/KzZikTLAybMQPdMRArHj8A0kUN141647lK1SgMEugm5+nIBbX5RA1jHte0QNFHuSlWs/YfximaeVL9zjBSrzpuAbym7xTJmJTBrrT/PqaTO1VO1JuPS62WMOM008OjGK7yKQDgZmWVPK5RZmlYdNsvwku9VmQ9QOn313CS9zE+wtdhvVJwVmb4r5Tr+dUr3sOkGOHK8/b9WPxzRzOsfxFJ3O4QqRvFcprNJx7UrF42sa6ilw9r3iWZ8ICH7YVCDVffmf2QX9xTq61xYdydP5og2cZE2vaf1CoIuKDB9CuC7BZGVbVWRYIWtn1CA44B79j4pV6MKTHnR3/XHmwgj/B/laGv2CSFs+ZWskFPP5uEQ07JxQLGNd/MN8VpGMAIJ1DV0TKfGLDMwjNr8I/OPpVQhe5t8UoB2n6Uf2yOxkbSaVDcrKRlDbRLP+5VFUvmGpjJaUlXmCMkMM7qTnNPu0/zZIiIrV4xfxgB+kUUVduWmIhBx2cAKAMkSB6yOKzaK7hAE4UeqkRhBpI1BQH0OpYcTbSBq55bTetQdwn/oVmOsdu3AEXmf+sD34MaI6n9bPcyEkcoz6uJ8LBhyXIQEsvS96vFRruiosdB0GkJ1WH3V8zW3HztEY3MWntxjfVDY1lPu+pdtUMjygHVXD4kuIQa17LBOhMxHs5FYialVg0HvRpJuU0hlnbwOwExfv3Cv/quIAmME/g2+2Ll12fuU/jweTbNEUsJ/uMD2RpqollyuuDo34XT9sQMqNVLSXOXRgBKRUUqD4SN6N4xkrRPL+xdBgG1/0HuCDZ9fxiH9f9AxEzohMD0Ys121QyXG2qUFhXRrRNGFBO59cPgtTSq2dmo8eTgFgqEVGp+OFF1JF87Di7YmVVELXCyS9JE+3vgRfnMKKW51gf5IUyOP3Mcg+e/DpPM2XstjxIH21fWZW0R0DlSWst1Bqe2YbxzFRnk7sJyb7LeVw4YwW/boWkDfzBvjQy/Y+t1YOYLHNVZwKMOPo9YVyiKiIPegFMOqqzw6m/owvJ+uQ/a6cKsOwwHAkwJbm/1e+yXxdW/qDktF2jPM= \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/privkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/privkey.pem new file mode 100644 index 000000000..21806c72b --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/privkey.pem @@ -0,0 +1,40 @@ +-----BEGIN PRIVATE KEY----- +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 +G22jN39+js9hhSU= +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/pubkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/pubkey.pem new file mode 100644 index 000000000..24b12e7bc --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/pubkey.pem @@ -0,0 +1,21 @@ +-----BEGIN PUBLIC KEY----- +MIIDeTANBgsrBgEEAYGwGgUHAQOCA2YAAAAAQQStZIThRSg98P+BO3exVKgfS8U3 +t9/rkw9R0I8+5HBOpKZptNph+N9nBw8NxrxZ0pEOXXd9yUH4L1s5HnAO+x302oxc +tBJIjnIB3qkSqjVJrTane0I2HIE/S/t5jfaHNMU0/9GUB3g5qJyB+lZyK/KtypAK +C8EyIaAtN3ETcKqcPxkkBhHKBHZsK9hbL4h0LrEoUvhdkJIu05WFDcR4+KmJeLFw +hZc3qlR8A7ub1jqqsqHCjzq1d+CgCHeGQ1nN96CHLdYCMkYxoxosJEs9v/QWuoZE +XvZNslt6pepPsGXMrBXJqfLPz+SzFtLGdfy6ADhfZBe4YbdG0cIah2EsJiMyxxnC +/igSLqKw0BuFW+PDocnHthBbFjdFzWZAvUk0cNiNX6l+i4gsyPB1huQmiRZf8wi4 +6fVuycl9vflJDfcAvWGgnjp416VPHiqwn+clmCyMlTMhk2WYMzmQ20d9oPGnFvVU +n9Ij9RMNuxcqprh0IrCCUOy6BRI4u9UBkfwIlrAHKCyr+9G8G5ViIEa6vhosDwuV +4VhbRcV3yBPLX7RNK+Op2apPvJypE9sw4zQpjjspUfQ0GVmIy4pJ+Hk+kDg8kxUC +abeEW7HJQ/hZNjN9yedAwByGkRDI2Ysc2AFNenkqUBQLZ2pqRAPDRVO53is/QtVQ +hFUFDLOJIbubrwdtyAolKveLUVEzQiJgONZQSYOxgCAe9NOROfN9DdRBifeVQvMT +tptgo1N/Y4xfmylF7bk+J0lduCiM6rhA2RuVdrtdvJfOb+RuyEK8YqwR29qhfKWb +p4tlMxh/oYM2TynBq3qJB3lCOsmzblcWpNGFIuENIHOVtdev4yiFFIlgxaopk4gB +Zwm6hmeIiOpQtyRPkKQppvBibDakp4kAgyxFTKx+shO23GkDehY/a2pxOueN6DkH +dNQ4ROw8XPdUektvGftStpJ2Z/hT9ERuADyndwOPQEnBrEURnkEHJVIiIdiBD+cd +30e2PdMPEOEx4oJz5SXBxukbOHYUngNbtBWGQ8Cv/feJXeQiEyrKUnONCKyvDbSF +7zYHOKR0LsbBs6RnlblzKLgLgcuDvndThNkXbCSkk3QNnCukexKTBMKe8FS0cpQN +j051L6YYJ1n8C3B1zYOBLnaJr3ISzZZoFgur8KE= +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/shared_secret.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/shared_secret.base64.txt new file mode 100644 index 000000000..34055cdb9 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem512/shared_secret.base64.txt @@ -0,0 +1 @@ +YHBnL5xoQRDnvsJ8wBbQ83cwzdkC8t+KRwhCfHuS3LNlSVws5GIEooy15Nnt+QXl+kThVsVrYmo3ijuDJ9Te3A== \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/ciphertext.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/ciphertext.base64.txt new file mode 100644 index 000000000..b0eb061a4 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/ciphertext.base64.txt @@ -0,0 +1 @@ +BKaRbcpDNabL799dlxw3D/YKV3zoOFEA85btG8LaIpRwrwy6PRDsyi31MdV5Ot24+LsQ3N8kipHdAozmvLH5IJJN3sbmGr6X1lTCdNhcxj9+sCqX+8x9LImhjC/t/bO7tKNIP5PfugpN04puJDCXqZMcHOChn28ltKGIxa4XhJiSyfeKbu4q9PUq7DoIQtYAT6QHZ/Xsh+PU0E09ECBvWZhq0wInbXBJrWmoQYu/Ec7L4ZzKVVfvwbH9UNEU9iZ/wHkq0yPfBVvZNgmEvsB6BWYP2x4L/4fE3BcRVoGshnn158QqR9wOgEUoFCWkkTE7jwpeZRmXF0i1b7/ikvWRKzaTSiftfyCtBOJsE/OSoPS+1H+z3LWlsm+z7lxSQxnyE2TI0BabsYaDk43FJoqPHYzxRDvar/RxaMTdvXfDj4Ty/sPfTSrMTgav1VKZc2OnDS+ahWqmh1WApGgvQrUFRQyjjOPwEOKNsO7rXDviSanhwd8S+Jb1xJfMhttStZ4QkYIfqo2yqbRNADtsIbRVMKNSgYVUL+x3mnMc12t6W/UFT+VjKy+6bkToghFbIQNdzJyU1cK7poSquaq9LiOPqoRZkzhw/cIfU917YfZlkIMYFFvhVu63pNFlx6IC/qyYoFwRWNbggcvU6BDjI7oowNtU3fukwuaEjJVPgjzyanRqGgENEXZbksppdVDMbggyJjQfLE1FxMRp2A+SvpYkz4L6UbNEfAqKrmELxpjz/nTcGVx8uMe54AFZ2Gk9Cpqvm2r7ZIzpoN8F+rMM5hUr4A2YZnqQElDYTQUYlvIffrwVImgBiVjBOET4gIrHT2ju6ki3fb4L5Vxa6Gbccz0X4cgoUPcLVysEMfrWtmgV0MDVzMad7vuoi3QZlm2eSv/Q1PLP+p0FdwLod0tOBpstl++/pAxqj8b2NFqNmoXkF8Bzld/NSfPNOYeOX3Y0FtO6+gxby4yofdYqGUPtTugoitknNdROFJXdovn1/6StRfM4/WFUvii2AiEwxK8V2QBCoZXOdJOhz8umUc61yTGFZQwen1nsqUz1pYC7YuttecOcGZRgtPStw4eNeAwXXq2+hIh3Wow8pmjs7fpLBtNVrbSSXaKVWbJE3+26DWimUMX4lykrXLj4o9EOkPx597TrJWQ8hLRud4cSa8ddgT3fBYBzHTt/RoPXt0iQYKxQy9sG5ASOWHwthYWti58S7yIpaU5dIzsG7WJZvspgtzAjHugXKLKaE1oizl9Y5Q/DIJTrWkhiMfsA0AQC19LFwCOFLYIv6/vhQtxvbF1pXlPHpISo1/XfiAZqN1XfrCZj4If1F8P0zCShggOekvab+uNzLhY16klqtQnxtm//LSLXe/0DzQoAGOFOVno0FCFuS7VeYpvi8btRjKil9jF9N0/TaGrWb73XHEa3UqUnh/qhwZEbGOZTVKQa9dnVGgPybOWjuYDeteAsiP+koJlB5HAr2711nM1e13fNzGk2PGYEX3fsozVw5KLwdQ4YKC+XUSV6zt+qTF4Oowv1kGR5lGYdhA== \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/privkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/privkey.pem new file mode 100644 index 000000000..e11165260 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/privkey.pem @@ -0,0 +1,56 @@ +-----BEGIN PRIVATE KEY----- +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 +qe8Vsow= +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/pubkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/pubkey.pem new file mode 100644 index 000000000..f6c81ffd2 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/pubkey.pem @@ -0,0 +1,29 @@ +-----BEGIN PUBLIC KEY----- +MIIE8zAHBgUrzg9jNwOCBOYAAAAAQQQQu8wDmgJyqrZhhd5LcJm5cQuxfdclR4/0 +zEwEBrHndgf5r0pZVDimxtus1ogg21xCrhAWsd3NMVAodecEv6Dq5xJeMVxgUgOM +5hS1ruZ+0NfBadptcPJIajIryvA7FFhn1qQQxVVmULGw4MIasYocEcemvSgOFhIX +6dMGY6BuGGMseIklNMpiieKRy4JYnMJaebtPtzUyvEBj7fieefotqKbIqJwiYYkM +I/ml3+IiGyeyzzhnwLhwz2drIIORPwdtiXmPJ+apm+ooIrWtzzsO2WGLAzWZh7RF +vhZmsRQ34wmgvCY6h8QuVdxyaWp0VgB3eISuCamIp6N6UQgageiHsuRlj7kESrG5 +sciibylhq5iKrIYFW9zHPOo+W4thioZX6KCS7hLEXlsUUGQ9ydhdEsd1zPqnBzs8 +LdwaLMYkhetDONhvFbjEa+TMctsOSgLH2khFWAZbUipmRTcP6hzFOCmJRanP6BBp +UsN/ifxnlgFtSslEr7lBHqsNTYIEOgQdI8hHGthmhfp7GnaM+zOTZfJbQTotpKmH +qNgxCXQMlkTF30aPieC76gu8SdhYGlGRqSS8RDemtQqQWkmX1ljPIpgNQCoLDNmZ +rjJF5JJgHFlt26mE96m1hKhzz1xXq2J4Y4owAVLL5OkWJmYUbGS5/YixSCsemZVX +OFsBnBS6bvFp2AQ2sRPGYSWv/MgmqGVA1HaKYREpeQK97zYMATYz4UzPeDMG0VIx +5IxJfMQ4poorY3tEzelpT6QbRarFOeS8mFywgkSDsXHAP+q6GtF62YWf1Ji8Vasm ++6lMHlk1ugqW3xAu5IvHkKkxxwaR+wwfz3dy5QwC1YcPSmxtueypHFsOe4AgrIsy +38wFvkKUkzJ59XIc8EaWR6AUlRFVMIRt6BVGJAFY6Jxmt1KvzneZyNWXgWklH8kb +EBqMnWpVQkSy3BKMA2i9cvEZOYmLDBVeXsxknIVZ6FcSdYd+3OYxo4MX8KEKcgIA +Vnp48zjB6wwxQfqCCPtzFFswKNoEAWRWvYwpq9lkV/O+65S+IBaoubN0L+wwVYls +BYdCJ3AZjTWvRyvMQRA/M4Q1WmhxnhAwhsg7irIlSLmmdJC4yeMcpPsjr9iKuKY5 +gumDyxpxRyw1gCuZzdOLkCadymFtJ9duFJRXElWsQ2goMcd4RVVZdCQ5vaYBkXTA +STZsuGhKyHIshcFOEBe3q2qEEUPDv+kgJQtykdexyfcaBrNQTXktGUZGpHMiMjpW +3cuLh/pIg5FZQrB1loqJZqIJsclugIpZKqBchiSVE+hZz8GWZCvLw5OEIfXIkNGh +64pz6KXKbcHPosBGzpSeS+Frr8W8TZkbrnWR2qFZLiWIQdaaG7qTQ6BiBCC8SmCd +MhNfOnt3urwAq7F/Dxd3PAcD2OM9m5kZ3azPE5MCpthMWTO/8SZbViWinxBPpEM7 +t5Zt6zKIGBW7FFLM8LSeT3eYwdzHE+IHsIp+gMMsfxkfv2q+QynCNdUZWZJC+9Rw +ePg8ciFZB8kHDIpXxmBl4jMrWrMhzrmSP0pZPvJm42A0a1ZqwzDHCxHIpiKy5JJb +qIGAXPQV21guhfshYXOLuGw47lNpLAcil0AqahrKr8ir0VHN+VIH1dd5zvpyEpXr +xEhwDR/9mn0xu3bwWB+EuXXt5ytIywM= +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/shared_secret.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/shared_secret.base64.txt new file mode 100644 index 000000000..f67fd19d3 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p256_mlkem768/shared_secret.base64.txt @@ -0,0 +1 @@ +d/2kRrphP/doe0sIsdnag2JD0s55mGOTFXK/p1qS7tj2Sq32ji3EuZo3wrmdjPU8fPNps/OrVfQINU2M2+O0xA== \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/ciphertext.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/ciphertext.base64.txt new file mode 100644 index 000000000..091bdeca2 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/ciphertext.base64.txt @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/privkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/privkey.pem new file mode 100644 index 000000000..39dc1aa9e --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/privkey.pem @@ -0,0 +1,73 @@ +-----BEGIN PRIVATE KEY----- +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 +eD4nIW/a1A== +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/pubkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/pubkey.pem new file mode 100644 index 000000000..9286cef00 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/pubkey.pem @@ -0,0 +1,38 @@ +-----BEGIN PUBLIC KEY----- +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 +NymcjZ270A3odts= +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/shared_secret.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/shared_secret.base64.txt new file mode 100644 index 000000000..b598937aa --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem1024/shared_secret.base64.txt @@ -0,0 +1 @@ +Sl9ngWtnAxDFEUi8HYZJisNlvFfTOmY3ZZiQcOSEkAA/giyzNhFn0Qihx+wtS0GjlBp2cgYSlYu5vMzm4unD+YT9r0dzs6xOWuDGPtFSSJk= \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/ciphertext.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/ciphertext.base64.txt new file mode 100644 index 000000000..01f3916ab --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/ciphertext.base64.txt @@ -0,0 +1 @@ +BIPbolndvsVedstGFFXQLBi/x4RLgkn6i3QTG3qeHnrs72a12KZm67V3404HJx+sX+LMCwAMrMh36BnEKe3buaLREdEBdFbS5O22j+GDs51q+Z6HMthIsh8WSxcJuHI0H+Kta1aiZqCDfrnknn1zR2/3VGH9Rbb4si5z0LVmTKiS18Y7xd5Votyhlqgp8DkDiOMJkvKm5jqKKmp4QUdxHozUAkYjS/cVcV4BeznpJbwNbKaTDWc2JHU0Za0WAFkfq02Su/TOozluujt+fVlMWPOJJRdHp3uPIqP5v8NXqZK5g4d2YI307MQXtteWj8/wGxAOtoE3WCaPZrIjdZ15peoc3TTDjy4g1/luZ2CPpfxDCbDWXocSv1fSwF98lJg15XBT2JB/Ia6heMNPHxRwfIxn7T2pjhrdmC4YJ2cNlj46/PNpXzShPrjlfpZxCM64IMOp04hGKLF2dy9D22M3ob6cKV3jQJKcQfUuuvHnPuztytvfVDqD1E8bqc0itYDX1x+nP+98XX2CpQ5TJhKGqNTJIFtkqBLdPXsK7kAQo+taAwf1oCTlnVygodFRMkUaJ+4M+ShdFzIyVOozqKgm48hSZ5QfygLtflsJtt/VpF6Ofxt/Sp88JEU8BfB3C+uffcAqXaKIDa1MzPJg+y1ev16Zcvnyl3agQYpGBSYO7yo1jnX2aZOKbkIjvZl8oK00pC/JezcSECJ54JinBf+uBtO7a9juaVQA/dzYVLeoBVLKksxoheN8coXlnvhHmouEHTL4d7b0/qGK6fYMLSLGti2Wxf3PuewqglYSofjnsOnoLgAxv7YCL+qMdyld/M3fvraC8MYi/ujDStFQ87iSonyW+XUh308slrHzwvrLX4mFskNDNMRsZrRy81Dkf60p39iD7XRCg800VaNrhaJ7NaHqsVL86jb35s2aUUEggVlRWmOmnlJhT6hx48TjShwGcM0dnWxWcZonr6gyKEi7mOtFUoL3fB20N0HY9BPbSEfmfa0++xzsekH5UORE8BUXk4rfjCaEp29UnKjW52cIS6oRKLlD4hMrvRth4BjYFxUY1YCpJgdJw+isyN0XCX83CaJ5U2IuZ24aAQ2L9AzPthqq+ygKC5CSfeNce9/QvJGI/fW7RBLxYF7B534vG0DNKAngtu1xcKJZWYbdipO/0dM1RWdp7Fa7etkIxrV9zstW6Mp2tlCRNaBW+SKMbdKqahmRquT4qb5/jIFoNZG7QHlKCaTF/q8eW7yFoCESOGqfY3HtTgMxhOBq4YAGMcKAMACdebwL+0T4NrGub038b0mbtt63fcIxtYNIFMFVjsbD8hyb+vGlM4xt85NPDL5FhjRKixggtjd1Azgm6d3Uy5sGN5Qn0LOiodKKwH1BK0hNn0XR7LghuXARXJx2Kbd2xDqdpZXcHAf9+4sPpzx20BxxrIvGFwT0L2YGDYQhWD4f9Sy+LnXi7MjrNVG+g3PqEmHUn6GsJx1qvSSP44RuqGXFQJTyuxUBE8qPjwzPVPM5EmXxJV6e2jp/QhfEj9q7bGeojFU3iP8I03LoxFpdEIQ4Q2LLFGOAqLI+pD+Z4+FF \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/privkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/privkey.pem new file mode 100644 index 000000000..37f391ac8 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/privkey.pem @@ -0,0 +1,57 @@ +-----BEGIN PRIVATE KEY----- +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 +qcCI +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/pubkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/pubkey.pem new file mode 100644 index 000000000..30c6a4f31 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/pubkey.pem @@ -0,0 +1,30 @@ +-----BEGIN PUBLIC KEY----- +MIIFEzAHBgUrzg9jSwOCBQYAAAAAYQTOvbIjyIRPpUdF2Vid8V5lfSM/N43s88g2 +lr4CHgY4gJY1hxLBgpInb13X7v+sEiXoaqvlvxbA+7bgPru21o11S8tMqfdSqRJC +xMZZE8HIxT4lNkf6pg+Q8D9s0gtkb7cyNMaXpD16FnbaomBhqH8YQ1jRGs+UejTC +a4yfSBbu2LdZGjJ8Ip2BSDEWgczVGHm3ZZ/EwqZJwBK+PIgUZxLWUkzA3FIGEBLC +WR6yAqce9MPgl4dYJZZ8+Wb+KmP6JH81qFY+cqhQULx45oSGFgSB2ABNYxMzKl2J +ZlejRHy5F7R3NBBY5AIfMYwv1DrllqeDs3Nvtp0ZNTCqmEHo6CGdEjmsJU+P4jjC +aJuOpciWYJy6mZF8YMMPlioBMKQVCcprmE/5MnZLaDVj0FHL5pKOdG28OiC0Ub+a +ZMbvUT3BG1waB7RmWYU3ZFc/R7Fn1gw0YsjWsRE8xwN1Wi1+KoELnMlFg6wotywu +FGkQpYhOxEXZ4szdasUfEqR6kjFFOUkFbH6MRJ1uAhof40tqrAnro5CLQjTVeEGO +0BQZ+blt5rivg8DAnLzSa4PoZ1TtDFdpqDevw3+zaSSo8r97SkiwVD8W8rEnqotC +0ahUZCqTOjq6RKAONUV10Sxxo4CJpCkdUyP9yMr1oc25PMwsog2kJWjbZAfo4gyo +MA2mYXyGB60DhFFr+l59FD/hS0G4ocyRBzY/tb01jEugsJ5GQaA/oMthtJ24uIvY +jIm19gchiXOwkEAEKy6aU735IQ71YoAQBxG4Z0LXqJKE5Ee34Tu1knWIynLg7J0i +h8sAPL3LkL0IxHIEF7eCyRnoNqvgE2dqBX7YeZ65CiPtsTlKdmrb1wwOzMuPBg+n +lJxRKhD/mh7DGbOnYcY44HMIJY1goaOUdle2+ldQEw4Bqadod6wYmSARxngbaDnQ +mq14B1CKtydO5lZ/ZFEzRiSqcgLjN4e26iuwe8UcVVnBCMu9bCTKkBBu151B5MeI +szDZCSmosGkzwqQHx1L1cJ4tybEygjV2eBNXYyJA41dCjHj20C31w1n89ThAEnZV +ZYnjBW8WNbHzgD7p1UpdzBrJuReQvFtkBGf8iaYeFSPBsIKhpSPypT6lAlv4fBoI +BLcbqUAtlI00lz30NB5QZsKn2ha91EXb5j6rx7+eRb8xyCtfN1Qo50f7lbq3Jg1w +pAmSYsXRkK7LiC1Dd7pPg0HO6YuAaoWvYL9DFQzgA4EYm3XQxo47aMce44UIwSkA +UxwCEKELUyh0CmUXVMeOI6gkOSs42HLnaY/5CmMe8XMMuTZopMG5MYBs1AQsqpcR +ZwzYER6zqINeuDupxpGB5nLXom0zliok+r+32cLTCUyWe26nwgvXBa6KDDUxF5Cm +LKw+OA+VcFhIKoznhEadXEcrdkVFY1WDPJFx1M+GwGFmtl+7OBoQ1cgGwleTcKmd +GspLSqXzunRP2ZLHaW60FsSXgRij8CjQln5shENAplpSaVqAE25IHF6nWAxsy0Uu +Frk9lzX1sQmuQgXtizkc8Wvo51vREBEY8X3A15tNdlMkN2RXuKIDdh0um614hYqW +eXeJCMTXUKZIca98mLhoUTkPmwdOA8w/pBp8hoCxdDvIa0OjagplI4pWF1rqwM4U +ws3SgECTjAOX5BFkR0wEVXsI1hBG4XWZlnO5RbcCyXgODzbJrw58wtkXGYn6FLlb +a42SacGeJQ== +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/shared_secret.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/shared_secret.base64.txt new file mode 100644 index 000000000..4b615fe6f --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p384_mlkem768/shared_secret.base64.txt @@ -0,0 +1 @@ +D1ANRwc+/Cc1sEipmhVXcGGuUVAyBeQIJRojX/EeYQqwpSvp1BREOiNah9yrR65W0Z9W2c5FiZ6O+GbfOczzAW/oX553QFu3X9sugnGtmd8= \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/ciphertext.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/ciphertext.base64.txt new file mode 100644 index 000000000..eecba7b8b --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/ciphertext.base64.txt @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/privkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/privkey.pem new file mode 100644 index 000000000..c068caa46 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/privkey.pem @@ -0,0 +1,74 @@ +-----BEGIN PRIVATE KEY----- +MIINVwIBADAHBgUrzg9jTASCDUcEgg1DAAAA3zCB3AIBAQRCAJGdzVGw9m1qJ1ht +ec2xc+gXss9sjRq93k0W2gXs+LjB9KnG0Ze63kj3esp6Q5XByKO8qOUoG1HQ2CwU +o0R9XIXYoAcGBSuBBAAjoYGJA4GGAAQAx8IpOxt2r9baJOXK/tqLn1abkG91cJOD +sFTZbu/1yO6c1EZFgdURqnPpLy4zwSbJn6S7zYZkvnvd6DRn6Yqt00MAPfII1UEB ++nbd393+ocFhJDRLrw2SX95KY7lVT348uTPcg/nc1MQ+xpxraXnRj/3zGE58GySk +iwTqqEjzq2VFkJN2cr5+lUY96MyV/G6JnCssGELQeze/RZmOCMQUFQu3EEtqtx19 +Y1/dHA4dG0bR0HPweYCNvBBuyWqM93fndL2SMq692ClSoHkZanWz4HrEgVZ8hUTM +WCZpVLYUGbm4iSeppVlyYWwvmBr+N8KJ67BVOyGcQV9GUTDhwwQgsKoxup3yQphl +k19WdTm4TEPqpbYr8ag3gcKM8RQ8dCjRLLSaDEyQ2bD+a2uPGZFQcqYg/GXGxLkL +Wj1xiieeAQqWwx5x8mLpPDJHhSPguWbrYHHcEoRO5ik7pljewo2k4kOdLFDWc0rG +OAMc8DeS+CkhK7efgoskZMEQO5D28qQg4paJ7Dk+FBiv9sWxKL1HdXiDEBtcJEGM +YI2huicZOTCZjGpxfJHUJwcV1GpU90Q17EpN+CZ6A27GyzFaaQVxOhblGw/8ewYy +ZhgF4M0mcQD8I1rsNGd1MBNpFQ49w6u7CJedUj50kxNdoR29Y5tBIMyDq2hKGFuE +WUYgomnF+Gk0QaYZ1a3bnDj7u0keFntIdE0eM1g7Qg+zVGielS59RJhmoBK5hiF+ +FZW/W51Go0FgxqFZSZUfi3B70CRkAnODQI8BaZabd5xiOlV/uj8PSAn1Q3ZOo8My +WgHD0AZ8sQWYgMY+N4ftZZS161QKs1PhxLsQUKnGuxBpK61KaZjl0Y0faBL3w0Fm +S5KhZmDbioxWwKzuCRSdMETwcJvWFIQebAR3dnRBR0rDap9KknlEAh/a/BhMYrDB +gRGFwoU+NaombEq3xkJ9WkLsBbhdVcPEFHRROl8Cl5vcyFNcukW5BW9QuDTp/IdG +PA7nRZlEF8c7ZiAfsxuYc8H5iEoZ+Vr6yKEuhhqt5AQUIUN6uSXW5pynO205OzuK +6wjR9Hpe2Sy14qUGHGw7dCgM06JG0CC4JJbBB4ukBySMG3mumAe5oweKKF9B9zXm +gC0JtMZbOyUzuzw7Zr4uIJuzsyptyAtWAcB5q8U+eXZqazPdwBN2Vy/DKXc9+gKq +SSSxF5UHy3voQMzi0b3maSnRKwYnxn/TNKm1wFbIZDtf9xIIMRxyd51ghr2LBU6B +M0A6+DzFeUxwiFF70VzhN4crShn2AMYPlprKxAr/yZld0QUQ5TsVoWbMlooM5Hl9 +tasA5j2m2GgR/BGd8GVUE25PaKiZUgxvN4sMx4wJNELrZ3PVg0IqBKgtFaBRuJjo +g2zQ0a1qJa0dm1VZHEpGwsngJYcZsrUZppDypEfrWhzYsqiOcMrvARHKxIpXUzp+ +ii7HJ627CZltw4WDgDYw9cA3ghVxOy+DHLN9GGdc8EK8mpBra43BAgwU51JCmLAp +MC+wEwIlhgLsGsPC8ho9NGCG1IzJk57x65O2pRkqxlMxuUoOdI3U6oCFsi6ggEJl +qMr0opdxMjunx4vTd4XFJ5J+gYpQJKLP62cPc87QfBlDc5XDOS9BBY2iaguzG3dW +orV4KKM8g6aFhXeMl4yQaLJ4IKQwZB1l0qOeVMXd2VmoyXLKC2CgYqPrW1zW6cyo +CXrIEjAZmxc6mkI8VBGFBS1LKwiaWX8EAho2/B5lwU8Lekt5fH+y6xZXMg3oOaL3 +GZgCGbsdF40t9T4k2cZ5AwldTCGP/LEqAA9TArgvTBmPw52P+xAypBfkmK3egp/n +Zlsj27Ls0YKBlogIOM5S0R/XGVUXp4MpGYqSJXkIhDkrpnjP2UywF4f0Kjq0vFyR +NUYR0wAqpD82WELmAHXN2FIKpqh5CJj/VzBQUMu5+SYVdVMpgjPcGLcrYVSKJ0+G +S6aYuUgMkWfyYpy/8QYru13R48nfsValVocvO5vNdM8KSkr+jH5DFIOGrBxxS5h3 +tQjogUHsekL+6L6Asq2gibVcvMeoh5t9kQr7haeNGFK8oA6l4Z1yl056VK9t23s5 +0kKKjLS4DK+1Ym4+jCMFx6ZixIKiy6Kx65gtohkNloYR0XLs+Lz1A3X3QoorC6QJ +N6XmdwxZ2TjT+neoOTNeTG79daRGiIsZHDy3iECSMLRxo8Tf92fMtBffkn7x2Fw8 +cm5F7KsRahsf9r8COXGwh5IWvETSlnkd9YW/GA49sgr1G77dkjGFZKA2Rg3fqcry +21w34wmV1YPQuFlx0yV5q3sfmGOsSx+wCpyMtkRwtXGac2NQSFYRlHX4I01gdBEL +W5sYVhY/bFEpi1jSuLmO65EjUUboBK1LY5PaLG1jrHN52JZWiMvxI2faLL6+9bUi +Y0jfG85ccJYBNpzDF5S85Q2LIiKAc1kX+bhN21/akagMRDUZIqdoU7ThZ3MSVXQ6 +Qxcro6NJGG9GdBUjk71mAI0gUZmia7WusUldQMu5c3W5qDWOwEbdqq6N4lC71Vkd +YLe7eie7qRPhV3a5MX7b1Ujr/M+HlyeLs4cmKMeD+4Pg0I+nqC+ZZ3AZYUysi77x +QlfAFmMxyHCDKyVnFzEWsDIbDHF/4lad1nluKRziKmRa0MGj0nH76qCn/AfPelds +tC9EqXovSJyj4GARCTKNubHT+guPEsuYo08p1BkHO0bcq5Z7rL03ccMP1ErxTK+Q +8gBACHnPQWXoR4ZMwLbJYRfp6hspekNrCXQTslAuWHO0sTcKFU/bE3uvto311gKX +hzBr40Gnh2GlsoBMkqVpZc1321O8Cwfe+EgD82k7zBaJFw0BEUvox2S+KyhpMXrM +gcIT+K6sFEQjoZYFdVMACwCBHExLx11wNKozs1ERykZO87uJ5l0TQKwv+Ixnyhuh +qLi25q0yyGhBe1HynCG1eHJVU5+HwXEl67Qxxa4aWMS5GFvpsTgF0Qg38Hno8Fga +1k/NKWNB6jts88x8SjPjmT0NXDNlwIQJwlBJJQYdtaq793BXKZjOqJyezKTWGy9P +NjKBoYZL+Hh3u0sA4D4p4FLoOooPeQ37ByQCFskYZrpqwAJHlJBn53O90gaweYj2 +4EMgY0ezEiGcaYBpHLOJxRZOeXrPYK5HGY+iq00+q4W3twnz+MOk9pFD0UV7dqhp +8qD7ZqIDsDwE2pDpAVklLCWwpMswcbF216jnyZjOCyrV1YeZe7yWdXCzC7klMhUE +PKemLLNNhT6do3ZXhV1KKH2Tcgk6l2ElOomhdnjBOKO3lUdn8YWytCHIxrA6kz8Q +YxHkR3qbm6OXGl54hIQ4M6S941is6LGH+ryR+8fQeVK2ZAippHoqdc9mYYjuFHth ++QYFJKUPBWrvUEbR6cdyJykC7E7g0DIy9MfjxiC94I8aUXnRVIMAkCGTpWadCWac +vEVSC7FCZ3LkpKsllJe2Ni9bF15tVotosAxMXH9lsCG0ECqYcB9c80b3DDyiCgte +/LY11GtgG3SL8hHa6RSINMdzU2Vc1L78Y3R7KsJEVmLh8slyhVtsdyVwTAzGiypB +EGyVdsQhcQiBaDxCEiYON7Ps7KRKKwxOq6sRRmvmSxrQFUXAZlTGdbhV4JVfPAYS +gYs4pCSz6jJD6RiDiMajSgCQ83fZy3utWW08BBVMuGl4mT3EhFvvoA0gvBqZR1mJ +N6vnc1eW3CNLtxKhVaLliL+CinvigMqjHDRYBiNiaowHGyRvtpyc6VP9g3XFGwif +2y1ttWUGIB9OhoeCSQd+HIz+G20FNAaw1GKaxSOu/LuhQYDCt26uhh4RFopRHHCf +c4thZB+/OcFCpZfgeyvgIrGJKEe7El2TccXFMLNOAYW7XK05FU1oBaD4uqrauptP +WLpItLeldD9llK0URwq4iKuxCWBIFCjVFB/gVSpkmM9L4yMsF3tR6ZczAwdNaDTu +9xTDl4lil8zttJ+J4GD7dodcPD41YGKd8bnstsIzUhos51+iSXZb+TvUhjaMwIfK +OwOTK6qHUyXLNmMWbE4XaWwGw8WKasFPFmqOJU2Kc1+CCLBMAZf8qnl1G0mC0p0E +NKn3W39I1XG1kAgtwovzJrFKZa2nt0kg+CKZQ0mrVxyVyEMFlpGCkisZOaV/p5K4 +0z6wpks12TTV0y2dtkb/sZdYFXAfJUEAwHSAKlj4A5LDExzGV079mqZ85KjYdi7/ +ux5mWhmTc8TPRKD5+ppL9oNkaKefATlCmsshiFeoOJrl1gk4IrlPdRGoc4Ldg2QQ +9WL3l7RIqA6OQhQVNcTkG+ph6NqftlO+2UCarhOwDP3Fx43+u06gPAzLdeUQ9vkF +c43w02f83igxoP+ZFe7rfimFaN1pznc6fuwnGNizXO+mu0reDTgqbgqVOOn8rUvO +z1koMRpMxC5egCw= +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/pubkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/pubkey.pem new file mode 100644 index 000000000..08db2f1be --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/pubkey.pem @@ -0,0 +1,38 @@ +-----BEGIN PUBLIC KEY----- +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 +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/shared_secret.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/shared_secret.base64.txt new file mode 100644 index 000000000..95ce567f6 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/p521_mlkem1024/shared_secret.base64.txt @@ -0,0 +1 @@ +AeTT4s5wCqkOoL7Ei2/zy8004prUeQaQ64wVFMLYb8sv8oCP+GzK8TWKEhxrXwsOzgQeQnsrEmWsgLl2sHCOl53EOoGXmwOiizYTuGD5+djXEo/kjz8O5JJGkYWb4qa/so8= \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/ciphertext.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/ciphertext.base64.txt new file mode 100644 index 000000000..a045a452a --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/ciphertext.base64.txt @@ -0,0 +1 @@ +hwwZoP2LkvVgGFfKpZvC+wiWUBI3TzG7dYBLeOmTQ1UQJucYOeBTMgAO1xYBm2Pw7YrSnFaLw9gh7nfuW/YDHvuQ6KCS1EN2KuK2YhEwAliBz8VsyzKYMqfHWEgvJoWuYGiXK5XqhXMw62/UAR7lxoS5K4hURat31sGVPfrVERK+z03wyH8uqgvd7Q6fE2E2zisdgt3rTo1xmey5PZBZkHOwsV/Y8K+SAcqGGu+j049GtPGnACMGycmOk7/w0NoRwaJKQ2hvw5dRWK/YmVYW8Fe1BdhUf0HYm+A0S6h5SXP4thiMLN6RChFpSfBj1PC9R1kYBR/LKNBjpCUQjMPWX0aOA5FrIr+DeDA+f2/sX81pjEtNXp5BLv7K7uuYF00S7zDdFlxeTKNRnokBrI4BrUO50LdrMMPRDfpmG2rWpPwwg75hCLBdtO3c76DTCq8jLl4+frv6WRw9FX58FgujoidhwqQIdCianhl3idIrbK/KnxH5b2MiAD4RhIdmwO6ggBrOvn9sdj09kct1b8EKNMnG8fcPzXSnGNZqRSEYnjIPyntCmOPM2X918FIfJVR3bCgDAweL4MIMkmbpTjKEyH7GoY9zNUTx9QmwGwjc/21+P8h45avDDae0osYUUllyKOuoBhkxHVLiqEurIwP6NxzYnMyU/Abh6rsSmOrkM7loPK2dT82b9qEynnprumlPrlbOi3ldlPjVLg0xS3fBmek+O0hdgbiJMS0yh/IuSlL++4viwk+syYFB2Q2yHc/GsYwXo+jFxXEKQAKZXsriovwvL7Wclity7TTb9uttp98VFncwCIaMV6zWg0YZa1ZfATY2MOcDSbE4ylUK1keDeSyznAsgrUoK7R6BRV8XMBzit6XoMmrAJdeYkPswTPWjasH8B5GSiK3gJrSBDsm58bd/HdW9QVV0oYnk2v5ZUOlrBiqwMCxb7c+tigAGmgsIdm2bOE5ywM+3Dij9rXkt27pYxdC9Jnq5Ge/rWh9XBnm6/5jRa/eM2Zu72gRUh+OGe55ifenmUGqA4cjZDgdTHm4QIZp6alJUzfFqkD+Xp/c= \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/privkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/privkey.pem new file mode 100644 index 000000000..ab61802c2 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/privkey.pem @@ -0,0 +1,38 @@ +-----BEGIN PRIVATE KEY----- +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 +qZemZDSnvzovQgvuWtdoSHyR +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/pubkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/pubkey.pem new file mode 100644 index 000000000..d3c2a659d --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/pubkey.pem @@ -0,0 +1,20 @@ +-----BEGIN PUBLIC KEY----- +MIIDWDANBgsrBgEEAYGwGgUIAQOCA0UAAAAAIP7QRX9NiUY5VSHjwOAssn0ESwMD +qxL5Lz1nJbrqUycWhHVN9YUjswBeKcpcQaV4PNEVUnNRgGqMyBtvxVZAX1HLOXp6 +Gdunl6g+nuiueTIjENCKlCItEES0ZnhuS8LDxPyXXEMMJPMHKhdKfDeoLOWzHEYB +QLQz/PxvlOxcnHWdreRrD8cjhKwKXJmzaqciQljHsicGq1wv8RWZ9QEIcixzs2qK +VKaWFNUU1MmaOsli2vggawPLrOabgOOn8Pdrr/OQ9BeIK9ZzOUpxMIHCfORfWfyg +pnNOTZOgwMtESYZSBla531M2LZokm1UFbHgHW7xRh6xrhdlqD5BiEWJkaGCxCxMP +W1ptZvtuzLqRYlnI3LGNttoOTQkonqCFGoBxVfdpjRg2TxpsOlK5kCKTilg1K4AF +ZgLLY6CZLweCZmInehcPbqSP48iUh+QpnVRL9UmBHdAPzcAYlaV8kleg0cgjATBK +DHWsZAOEhkGaXBVxf2TCAduMmBZEzzaejZA/GyBriGYPBUZdnmywpdbEnlV7BBOu +EZuJ1mwHSwwUlVVz6GAaqcGpXeTObgGsLNyT5VRc6ZMIpGstXZWxBOeC3/SWZtZv +cQjFEoJpRbJ3kiRMQFMEbjud1xGs9xIJ6xMqrzBjAru4f1UfgBIdSBlM5ViX6htL +PEyH63GMNtJradKQraUyHLsvhHcVlqQUJ6IEVdPMnkAgFtHOntlik0sHFJo7L6Er +DJYpO3cg5DCnWPEkAbMho1uswOCK/umxjchMniR/osBjOtSMj0UwL9cPQUoRQGGv +4dyDCyUElddP87bCBiHD2EREMHtMgnWbuOFdJ0jPksh8O4XPx2wxBROmDrijvBWX +yfuUCOOYLBWgYvDN2BPGgsGHRacNFIx17vJpi3OekKnCWjEZakh7fJq+z8oULWws +KOS6UVSz/LkpQ3p9bARCNcorfcNsfXKhfBQiLQaB4hMYN+Fa9WCSszS/jip632JK +ilsB//Kuvcem1eI5KggGV6F0l+kY7UFtrShIQOMiKJFUzix/UFqBtWka6eUWKXYO +8eV61VFUrec0F4MYxA8m/pu7MkpPV96OTV5PpES4oQjhpFO7nVP7ZQy2HAU= +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/shared_secret.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/shared_secret.base64.txt new file mode 100644 index 000000000..10d12fde4 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem512/shared_secret.base64.txt @@ -0,0 +1 @@ +7hJ8+oBW2GIV1eKmGOcnttH04y0mPoeBoGsmcr4Xtz9oXo61ZFQBV/KNgN+RE2xEzm/Wj29nXoqOUUSfrexUHw== \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/ciphertext.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/ciphertext.base64.txt new file mode 100644 index 000000000..1cf946d9e --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/ciphertext.base64.txt @@ -0,0 +1 @@ +AchUoK8V5U81BsmtjOrYkvWkPF9WuSKjusg1TRi46gNuJ+hzIc+VsAejzTwcmFGQfhANplyjA18cg2Lb85y/HF89EdXYY6sevo5phNutRONPNsjOVtPFerDIotHmERl4JSU74rgH5Ib6XP0fQj+3rZWSSaj0qaDuJWiLelfMcN5Sr78uEbZlE00AJkQwUpDQP9pnd7MPtgAlJ+TLB90cdSL9dFlSBJWYn0UQ3W2yqYIyxV24IoAwteJXFz+7AvyURAMYc+JcUfmOm50SH0iqmO17P3Bp0aBFfQz1+60CmPNwVncSlGSNVbDrmuGD5/gfNUcCqjX6kjuz5/UYArtUWn5J+h4zBL7Qb2zy2Rnulz7f+MQroKaXKSrGNMY0IzYV3sLlIqX016yP4Njl9a56PKGEdZngRJiln3dASYcfKqD8ShQTx36A6ldotBeOo0vf3hKn5NNKnE0Mdmzqq62bGV9kpTpD5zoGicSzh0qrmya+h4n7rVQjeP0Bg7tubVNPCBkjIikgGt4ZfTFOkMyC+SycHZwJaktqnEVz9HlOEz1M+ts2O6Kya79D3ecT4Dqa5qnOjM9EcD9tIM1D9JTnPXYUclLXZXiJqs31BTR/DRhw9L3WbF3l96NMVWu5eOzOrNdcAVRylg7hDGOp7wPxRBvof/9JumtMauc4c/C3smHh16uGhPojwebTzuMtyEkeyE+pKtusvOirGQg8xpubgTpG4tYOOrFNR5/QVBLbDBvBq97Omc4CeHHnj4q9ZyzWtgPpToCXhhPh7ikrA4cjHQVNH8nXu8kTN6CdgHfMpvQhF1iNepoeIMGZNNkELB7rGyQDhKVdmLtWH/evxjqlEA6j36LeBKI+CWko1cA/tUM5xTjCf0iG4b04nbYe4SxaQAFaEVXrAu2q3uku7PXbeuICIYHhBhc/kJmNhWUnshHhd4PTYhnfpGCDdK24SW+r37a36XbZE6DxXKzmEvANludhyZoT5KKA05bLNKf7OrWW0EJZTyRVXsm/vwCcrCxSX4Adn07uw+vOujfVrnaBAF/FoDFEVlWS9yzWDYKLy4iPKm1ou2ZEEE9yP3tEaimo6GC3IOUdVL1/Z1v/xYbp1nU+mwFpFSKgnMeddIBeRK6+3aJvdwbFvM9qNZVEVl+UsHyJ2LjxpB08pjvKNflF8r2VZuEl7gDkJyhEUHH/lBd1sSBqt1Tlc4kwd+7uUJbgfzYZ1nc4u0OOptEnHDvx+6LQHiTWuQGi0JuDIo4yqjO+Q2lrsvgbbDfYL7hECUiNJAVKqZFu+24XMFBIAkndf1xog10YPuHvAs59MsaatDmwf7HulDg2X2noPxfcXhnmp/MyHhr4+QJUVlzI/2hJ0wWGb7UR8Sz6tCSLsMfZMIE/VPzk7NNEU8D9/nBJEAHcMZav72UojoxFSYGfNyH3d9fJa9DT81JL0c9UvNVkciAmYRF6oVduP7dcvEbivEwBUHMze74iD5f9vfnm6bJ1mA== \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/privkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/privkey.pem new file mode 100644 index 000000000..8a26d0727 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/privkey.pem @@ -0,0 +1,54 @@ +-----BEGIN PRIVATE KEY----- +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 +5x96jZ9ebWr120mC +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/pubkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/pubkey.pem new file mode 100644 index 000000000..58b861fce --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/pubkey.pem @@ -0,0 +1,28 @@ +-----BEGIN PUBLIC KEY----- +MIIE0jAHBgUrzg9jNgOCBMUAAAAAIEwHre7MrN8D2huRKUx3/8pAlTzBwlSgtC/9 +ZOmS6Vlu6NY4OFKieoWNstVLsSBYzEBfktlodoMFCOl7sJy56jLCzuxvzXNt3Dy7 +9TWZr/HEBnok5sG2tbEViDOXkMoYvpptnVsO+5KOsywSUsYoroQyA3cRqJIl1wo8 +P5a/KjES68QV7APDp+UL9JxfYKs57oZX7dVHjbFqXonO0gVuaskPioKsm+k8iEzI +UyR13mbH3dVSSPSi5Zt+g+kRv2SB+vevG4dxRaymF4VgvytGFqwylLsPtvDB+ByD +ioGFZsyi4Px6RIJqtvNjCJQSPqPCyRidTFGAQNxCMkU1S7O+VExZgpdVXlWyj5Cm +DwEPLfd3dhJfobornGMm+EIk0+xnGUvE77nCw2MpzQXDHNhhfsAHerybgCwVfggF +WjiOVHokmHTAimkYYhDMUjgTzdWRkXY/WpYZFtQU0yRe5wBx8lHMwgNiG4EbNcMt +cChP1UW2v4zAOesBxxhnvKIuy/gR2PEy15OEUgpKUauKGItRIAV859m0dGi0r0Ca +WPGkISps58FZBdQQmMxt3RVY32Y3oroiM3od/sN2/yiPqCIKxltEFOlI+imAeosi +2wSw2sgglfDI8gxseNEv4VxU8BFqy6pFe1Us0Nyjf2w5nPGEzCcZ9fpT2qo1iDg7 +xZxrFGwgMyYJZ5mZZrquzKrGX/jOThiqKvOGihopg2MDZUm9KswAj0ejeGoDF1Bk +kzFfnHBCrjUiMwIifzAmy+QmoXRawoWDDgBBuRW/BFaaJuXHzowQqamUrrW2ShO5 +dUtEPgjFLudNDiW8xJjJTvYiU1KDfpaY5lcgIPNB6gjBYrdgQaxUYAJj2TBDZ7qz +itInDwplbRaqbsE9QciUT6VCEBmeZChWFFNG8ok9d0t/DGI8kypVugd8DpzAhjaY +W7w08JswO9qCTEu79fVhYVJ4ElG9MYk1upDNBOklbnOKhsIbuLpUmLV4FfwTWbis +rykh7huw3oGQWoko1UOY+qML5UDCrtBTCmEjlskTDkMwvobA8EW8LuMDfuOCDyWd +BAIJNlOM6lBWdfZy19RFAZilwqgPbIQtLLKAdnFggwSnMdyavYQ+lGY3/rEidtei +z0cWXPSOTsazyCqcwMt7JgWg7VkvoEQV4Ow+G7gkPdSI51i0mzRxApIR6VduRpxn +iFVGBCCXr7uIVoUGxPnBm8FvkbJrNxUyEaMvb0JU5AWzJBWhDCA8D6QRO8atqtN8 +2dlNtwlB2mOo1xttWldRVgDLNlQ8DHdsiqdU74KX+pSkNulafvIcMVIpS4ZAatGX +64xBpUKmvfUsmvdl1Wif1hJ4RBQQkVoIuplyVdJ6KFcHTZR7CBiuD3eiq0KmryW0 +hXNNUUEjrqtu63SBvFUoZnmCEmQT38Geo5zF+NIrUyNgrUccBPGhUPCBMhaaFxJH +ZoaF3DxfhDq8fEGfQUUwLLE0scqb0bumXhaE+hU+csN2BvZfB0IMHVlADLeD9RdD +w7GHkkG7YKiJvIRIL4d/v0yjgvmPhFObifIfYZU7F1VsbDC3K4hvsGt5S7E6j7GV +/xNQwwKn4iVToF2uq/wMtz/egMgJbtEy3iWDob7/48aDOjAElJE= +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/shared_secret.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/shared_secret.base64.txt new file mode 100644 index 000000000..897c5f816 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/x25519_mlkem768/shared_secret.base64.txt @@ -0,0 +1 @@ +qLSUgJ1SRndvCC79DVIml2JI/zqswuDkv3CjVOo4ojEaTHKkrfdRcK3jCBAid++kdoZHJcR3IWJdZsHjaQHPAg== \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/ciphertext.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/ciphertext.base64.txt new file mode 100644 index 000000000..357e6a8da --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/ciphertext.base64.txt @@ -0,0 +1 @@ +StN9m1ic6w7VCPWvNudMWzWfc5PO5FH/fFvRd+TllFSm0q6clrvc/Tf3mAsI6fdI8kBCiZjWHLNeVUkJc/F2bEm97qa7lfaAymlE+sYov79Tle82xAL8UTb80fMnIiO8/WgAi5lUzgDzAC/Rl35EoSfQN7lP0Ti/E0IJ9VRXChYa2CteazYQm0SzRukjmmtF3McFQBjWiuYeaUVT2GsvavGi0Enc92hK6TbWF1717wXRYEGPFb8x+h0XOO7HhHvh1DWL++lil+h0aM7u7jIZUz5IgqXBvOs9GfKMkvaMB+saeV1v1wzWaAhZOxIJpEbPgkuaqI1YeZvlgBrUg1/YxfvJFIkTY1zbYVIQSUjhqAqMgkj1dY2lAgaWWIVGGCOFYR1oXV8cr+sKHljdBg6l8YXKNsQUPq+5oI0Nn36GcTZ+bybXVpfeWg4H/Lv+nuRCdJ/E/AubrHk0PUp9fuSgFvX/zGe9++mGr5ai++hyR58s/j7yHSdE60JAnsAyXNgYsfSC4b1ZS2sM57nAbLl2auGpCB4LF25JgyWyPIGpBkB9UIx7nktR/oCL+pyc+Ox43CcAi60+ZySQEuOcpBrgtDgt0jugSi6ImRf60yGzxQXDr76l9FoP52p9M6TY1udRysfFZmWm9yuSUs3IK/VPrqwG2vdiaHMND+F1n2ANEW5E8aPqwsq3rfzMBwQY6mR1ud4R9UksqXFqbgtUHz5vQugjLMrRcmPtE3g4r+LuvyxQOp0T1NXVPUg+hLUAEte4LCkZWxD9rBIB6zfgWrmIy4kcudJqwMV4QFbD+cJ+GE9lah3rgyp2XiXKqI1KtvJy2oJJwh/KpLmDDe5D7V7YUNj+pFe5FxSq89vub+KvQD2pbrT9CnU3Q7YIhMvTFG4hUqdmJN02LWxPHYl+3zBk6hGL5AzUlWQ0pz9p6n5BEHGB55ZjCUE+hSmdyRv5XGA7fTV6u2CUnWeTrWekdWfg/lrAd1gLLR4VGGYsTtFqwrz+z9q4RL6bH74bO5S7jl4wPWTn5fxCU24rIU+JV3hWxpxDHk3V+/Jq0FGH44n5MZ5mIsc++Ys5c9G9pNiXkK4I8Qx968riOZCJVbJYN3HDTDBb/UP2gkh22tgT1NC3d/PWbBzxyjHIHEP6qsM2ixZYDjKiC0abD6oICj+t7ckys8BIViZoGi5THBefCxVlVY2z1oD/df9P9uLK8ymMjqVR3bLUnfewVAVyc8EkwyMYreo/sFvAXxYhDr3L3to0FZOVB9+TmxmD0CVaIcEW0qbpCCNbUbS8Uw086J0uyEmNbtooh77J5OZ7XSBZuzQhiCE5er68KTFCNoYfwkcmHaKU/JswhjZ5dvfzby0t5K522k5hw94TeSTRvRsTmujkls6UDHjPo/9ChUZ2i59gCeqogCr8GSm15YGCkIzK7CCITYuaMyqmWqLsgnOBOJNBtNC3pEfz8Wltwl/GRIIlr2xs5s9jNsI3fPhwE5ZJwbxfdU7ltbYZNHdJgYPhsBgNIHj3/PZV7wqytg== \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/privkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/privkey.pem new file mode 100644 index 000000000..bc5a5410a --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/privkey.pem @@ -0,0 +1,54 @@ +-----BEGIN PRIVATE KEY----- +MIIJsAIBADAHBgUrzg9jNQSCCaAEggmcAAAAOMSs9jb/NSTI8OnP50uP6xI1KXFj +Ou2tx7Aaz9Y25d1GDurbxz8nef8e4uYPd9Ob8yvxaw/Y7/XQ33sf2YJdL+ucaetW +ptUGAGAeunZxuOxaOGk1qvuJ/UCNiBQVm2cvG1QfpVdFLbVw7xhNysS080kbwehl +XEBSS4I05JFm/ZNOe2yt6YuLSFwH3eJRo9qPFMfM+3mNyol6kus1c8SYX1zDkYR/ +/ErLE9NvqPKkzKADzWNZHPiOi6YZG+yTLbo0UUYjyai+LLwTgYFN6fxJuJxjsDFq +VVVSbrJnMLsdy1aTSveLrxVWEkg00cwQMsR9GDidOZlL6kibFuCSdByd6QEn0+tf +o/kjXTChUrICdMmMHdfFzVlXpLoiRCOosYaXZPZ4poVG9okm5xhI1IErmnUM/3xp +8ZV3cuwjVitv7BbJ7DaUUjuNGyqN47g0GCBEssObEhm04yJelGC2yBGUZ5gKRVKt +w1nAS+mJ/mtxDCqLX8OzMWqgqQjCIZO91eGgpAIEfYVdKBQt9SXCi7WtuvAQ4hRJ +VNqOYMawApYR6UdbP0k6m4FmT6QBmxgC/mioydeWUGOc77SKbEq6FzIcRWfDe/PK +26Rp+3N87KoWjDG0Epx7+CuKyLEAW6MqaCyzAdqDBqEUffjFfoIM7tlrpXnFfVtg +srBvoqIr1gu7eKy7nMWiNOOuFqjOzZLJOAyK+PxAq5K5M0lyLvGmYaGQQ1zP/7Y7 +FLa/taRjraxvXCeYqhhgUKllw9U3Y/dAyocsn5BhMfwbRDdj4HuPQhJzveGsq7mx +QEPNkNCb3CMueMIoZludWiti4paK6sZFHpApe5zB2rBWGeUPynxwz5R/mMnMhToX +bxFWKcIMyKQqeQnGncc662MRyRBuRUJMgQAFPcutSeUWmnF9H3ZVMxJMmzGUUlm6 +WcqA6KUmplZ1PccP7aNr3xGt1cImn6iJEsGLEpq0s0BPRJyj5Ti0r2W+9Yp/m5sa +5tc61kWStoRWkeBUvJUkN5tK3aR/k8Ve+1ixuSxwqXgr/YBMoES6o5FjQIu/QAVy +L9lty3FXuGsnyvBPxBfFVOpYc/SCrow8MQejnkWD8AULnwukFhZz+IZC0eCG3xZU +wiDNeHkxUKpnaOctZZnDT6qWvOyHjbDLKcdOCkOo2pCrVQPHbWM9WpGf9MpH7Qyz +ltCYmRnLl9qje6MK7aFXc0Qn3wKSk4KMDlANSgac/rOUrWJIGIx0Txk/owsT5IzF +1EKrdzRajxGmD/kvhxNq+Pd2YtESCpRvUUTDocgZB9In+jyjVjefkKy5e4qz9HUG +v1AMTbUjH1N4hPNR4mw4h2Qik1M0P4ARrWZt8GABzjYYcQkV+4yQpcZTEOkfPrGo +/bRCsSsqU9x0ptACIJd8+ZgFMTlh6ayCd1l22VRxZAWBG1Qy5MBW/mSP+EMd2hpn +BzkEnhjPy8muoKdDn1uRKce8KVyzQGCFcoewXqgQJwUC6PampWdYruhOpEEj1Lsb +gIbDJqq9AESrLGlDSFkId3llMPBdXPEphGS6iMp4HIQwuHFS5dU9mxCGL7dwEfJB +WbzLUJzMK1R3b7UWdvM+p7zEvWKpOKR6ZhsHpJGU78ALYJQV8thd+LhEy0J9uDC+ +bHq5Vuc0K8a7I4WEJLi3T2olbyOUO7I4fZoqUCkREZge7jRz+7xPywiPcmELi5qQ +UGolepFZTkQWBdjEDECIaau4K/ACx0bNfbuRiERizMJd9rYkx5qhNJqppdoXHWCd +r4BjgvEEJMLGbjFM2OsXshRuVzNgB/qIPDGQ7eyvlAuSMtF3w+iPt2VRsZluI9vM +b0xWT1OZ36SJvkAM72nDOiUZZRV9BmqZStp2eJqc68SaYibOsKx9XoU3E6yFdgnB +cFWOguoo3FhZMDGyuNAep4VFcCWV2LR7xzoyiNC152dctalWyeVX4ucF1pi6BvBa +j3qVQDK4NCltBuRCE9dEKlZpEnKftse7U2NE+uuvMRkMtQw7Ipt4BjJdzmUZwWoA +ASLD2+Q+HNAm9Up6bFCI3ezD8CYI1gAMvqHIwKlYU5lJoIWrAACQx+eXdaUEuNme +iINBaCh+W9AIeHxVMJWR0jt4XQy6k3AL63eXIglZvONfXSoVOTd+a2iUyQsHMdOa +aeKWxAZSrRtWvkq/FFBvjWaGrhiE9mLGaiN8U2wKWQqfvFW/T2t8GnVqmDXIRuW6 +Cjm5edWIFiy0Z1Ul+Zkpi7sJzSesq+bFf8RwHEbMM6uxQDRMIgaJYuoJNaAT+bhZ +tzfDEQWoqwh94XyvnVHF3QlV0jMXDYhyhJiMYBKzZTmhIJtjkLOBxohI0jOgazKJ +bUlZ5wkYzMYNUdqNQCfF/ysRJKA7vWHFDQQNb3AEBXsy7XyxdTQbm6FiG3SCNXOD +WXSvh4I8RQXGy5SMPppsUUyjc3pcKrgaveQHVnmBsgURONUMlRSaW3IUQke94oUe +mdOdP1PKBeOX/gFJ4Uyuy0VzMXELkrRz49C1lEh13+uW3WOscjkpUxnOz6Mcy3p7 +DtVLtVxs9ynOifhhMfmXbtCPgcSagFokJ4VKr8JMUcQ6LGhkgGnASLIHbXmlytZl +ffV8/aQ9+jR1C9oONSkh52ZvpZYxCvkvFdAUvOqrCmley3dsKEIQ/NVlQXK8a3TE +VIYrWbykbFtKjUEBypU7rKugO3d+EcQqnxInTNGMpdLNWzhD1DYGjeIIQrAneWll +PonJjzBUrKmuPrpUMedNx7IC0FCbMYlqEEAwl3nBHXETtvEUcgkf3tAEHySMzpUK +owkz4oQ3pGdaCXgy8Po8AFqZG9FprBp6EXAI14CwFkykueaofWBtvqwnoSi7gze8 +XqmJA2cwfkAO8Ec/udaPa+dtlMdshPLP8VSJyUkv8KZImbR3IKFa1xdahoVA1RZs +s0UMQJmUOrkYbzJOO/SC+7M5EJRcMioytOlr26tk9Qka81YaAeoW9aodSEKhjCAI +Tae5Vuwwvsx+lJx8esc+9FTEMyqIJJand3GdhFNyjCtBIXVk6zWnKJOK6VeiBMCR +makFF0BY5alWP/Fj4MqSAiCcyDF1+/V0IadkaNiJy1kuIxtgxIIVjGuOT6sGNEwI +zZZVmeY+jWMn8eh6ZkuYVMvBS9K3/FRLgUObpYgI0qcFBOKrbjkVxZR481dz8Qq3 +Fmc6xDsYRMLxEsxlUGXp+Aa4Sf140nQIgJcnPii3ZRI+FuVByV/5rsLxJ687aedu +KIG85kSBwD/L+hPhYf1YSCq530TEvLqz0yvhVCl09pw/yjXJ +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/pubkey.pem b/crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/pubkey.pem new file mode 100644 index 000000000..3bb8e949a --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/pubkey.pem @@ -0,0 +1,29 @@ +-----BEGIN PUBLIC KEY----- +MIIE6jAHBgUrzg9jNQOCBN0AAAAAOJfCMWI3v2mV4tKT/9Q6sWfD8hNDcsj7Fdue +N0KihYKwtexWu2vXlq/RCwVFcc9RITJ69J6tCrVe8thd+LhEy0J9uDC+bHq5Vuc0 +K8a7I4WEJLi3T2olbyOUO7I4fZoqUCkREZge7jRz+7xPywiPcmELi5qQUGolepFZ +TkQWBdjEDECIaau4K/ACx0bNfbuRiERizMJd9rYkx5qhNJqppdoXHWCdr4BjgvEE +JMLGbjFM2OsXshRuVzNgB/qIPDGQ7eyvlAuSMtF3w+iPt2VRsZluI9vMb0xWT1OZ +36SJvkAM72nDOiUZZRV9BmqZStp2eJqc68SaYibOsKx9XoU3E6yFdgnBcFWOguoo +3FhZMDGyuNAep4VFcCWV2LR7xzoyiNC152dctalWyeVX4ucF1pi6BvBaj3qVQDK4 +NCltBuRCE9dEKlZpEnKftse7U2NE+uuvMRkMtQw7Ipt4BjJdzmUZwWoAASLD2+Q+ +HNAm9Up6bFCI3ezD8CYI1gAMvqHIwKlYU5lJoIWrAACQx+eXdaUEuNmeiINBaCh+ +W9AIeHxVMJWR0jt4XQy6k3AL63eXIglZvONfXSoVOTd+a2iUyQsHMdOaaeKWxAZS +rRtWvkq/FFBvjWaGrhiE9mLGaiN8U2wKWQqfvFW/T2t8GnVqmDXIRuW6Cjm5edWI +Fiy0Z1Ul+Zkpi7sJzSesq+bFf8RwHEbMM6uxQDRMIgaJYuoJNaAT+bhZtzfDEQWo +qwh94XyvnVHF3QlV0jMXDYhyhJiMYBKzZTmhIJtjkLOBxohI0jOgazKJbUlZ5wkY +zMYNUdqNQCfF/ysRJKA7vWHFDQQNb3AEBXsy7XyxdTQbm6FiG3SCNXODWXSvh4I8 +RQXGy5SMPppsUUyjc3pcKrgaveQHVnmBsgURONUMlRSaW3IUQke94oUemdOdP1PK +BeOX/gFJ4Uyuy0VzMXELkrRz49C1lEh13+uW3WOscjkpUxnOz6Mcy3p7DtVLtVxs +9ynOifhhMfmXbtCPgcSagFokJ4VKr8JMUcQ6LGhkgGnASLIHbXmlytZlffV8/aQ9 ++jR1C9oONSkh52ZvpZYxCvkvFdAUvOqrCmley3dsKEIQ/NVlQXK8a3TEVIYrWbyk +bFtKjUEBypU7rKugO3d+EcQqnxInTNGMpdLNWzhD1DYGjeIIQrAneWllPonJjzBU +rKmuPrpUMedNx7IC0FCbMYlqEEAwl3nBHXETtvEUcgkf3tAEHySMzpUKowkz4oQ3 +pGdaCXgy8Po8AFqZG9FprBp6EXAI14CwFkykueaofWBtvqwnoSi7gze8XqmJA2cw +fkAO8Ec/udaPa+dtlMdshPLP8VSJyUkv8KZImbR3IKFa1xdahoVA1RZss0UMQJmU +OrkYbzJOO/SC+7M5EJRcMioytOlr26tk9Qka81YaAeoW9aodSEKhjCAITae5Vuww +vsx+lJx8esc+9FTEMyqIJJand3GdhFNyjCtBIXVk6zWnKJOK6VeiBMCRmakFF0BY +5alWP/Fj4MqSAiCcyDF1+/V0IadkaNiJy1kuIxtgxIIVjGuOT6sGNEwIzZZVmeY+ +jWMn8eh6ZkuYVMvBS9K3/FRLgUObpYgI0qcFBOKrbjkVxZR481dz8Qq3Fmc6xDsY +RMLxEsxlUGXp+Aa4Sf0= +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/shared_secret.base64.txt b/crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/shared_secret.base64.txt new file mode 100644 index 000000000..6c00592f1 --- /dev/null +++ b/crypto/test/data/hybrid/oqsprovider/kem/x448_mlkem768/shared_secret.base64.txt @@ -0,0 +1 @@ +lkJQK/Q29uIW84gTk+fc/BZhOlcZUq0T7jcrvKWl/CZUa41ieDYDbejzGs1NKFNXOJHtae70H7HiCnewv9LyMHkJBBmbQhvCKavLqR8hqq4fQxK+I+ZCqg== \ No newline at end of file diff --git a/crypto/test/src/crypto/test/PQCHybridTest.cs b/crypto/test/src/crypto/test/PQCHybridTest.cs index 636ee2dae..6bf0039ca 100644 --- a/crypto/test/src/crypto/test/PQCHybridTest.cs +++ b/crypto/test/src/crypto/test/PQCHybridTest.cs @@ -3,12 +3,16 @@ using Org.BouncyCastle.crypto.generators; using Org.BouncyCastle.crypto.parameters; using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.OpenSsl; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; using Org.BouncyCastle.X509; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -131,6 +135,21 @@ public void TestSignatures() } } + [Test] + public void TestInterop() + { + var otherLibraries = new List() + { + "oqsprovider", + }; + + foreach (var lib in otherLibraries) + { + Console.WriteLine($"testing interop with: {lib}"); + TestKemInteropWith(lib); + } + } + private static AsymmetricCipherKeyPair GenerateKeypair(string hybridName, bool isKem) { HybridKeyGenerationParameters hybridParameters; @@ -181,5 +200,68 @@ private static AsymmetricKeyParameter PrivateTryEnDecode(AsymmetricKeyParameter return privKey2; } + + private static void TestKemInteropWith(string libraryName) + { + foreach (var postQuantum in postQuantumKems) + { + foreach (var classical in classicalEcdh) + { + var hybridName = $"{classical}_{postQuantum}"; + + AsymmetricKeyParameter privKey = null; + AsymmetricKeyParameter pubKey = null; + byte[] ciphertext = null; + byte[] sharedSecret = null; + + var directoryName = "hybrid." + libraryName + ".kem." + hybridName; + + if (!SimpleTest.TestDataDirectoryExists(directoryName)) + continue; + + using (var sr = new StringReader(System.Text.Encoding.ASCII.GetString(SimpleTest.GetTestData(directoryName + ".privkey.pem")))) + { + var reader = new PemReader(sr); + privKey = (HybridKeyParameters)reader.ReadObject(); + } + + using (var sr = new StringReader(System.Text.Encoding.ASCII.GetString(SimpleTest.GetTestData(directoryName + ".pubkey.pem")))) + { + var reader = new PemReader(sr); + pubKey = (HybridKeyParameters)reader.ReadObject(); + } + + using (var sr = new StringReader(System.Text.Encoding.ASCII.GetString(SimpleTest.GetTestData(directoryName + ".ciphertext.base64.txt").Skip(3).ToArray()))) + { + ciphertext = Convert.FromBase64String(sr.ReadToEnd()); + } + + using (var sr = new StringReader(System.Text.Encoding.ASCII.GetString(SimpleTest.GetTestData(directoryName + ".shared_secret.base64.txt").Skip(3).ToArray()))) + { + sharedSecret = Convert.FromBase64String(sr.ReadToEnd()); + } + + var pubKey2 = PublicTryEnDecode(pubKey); + + var privKey2 = PrivateTryEnDecode(privKey); + + // decapsulate serialized ciphertext + var sharedSecret2 = HybridKemGenerator.Decapsulate(privKey, ciphertext); + Assert.AreEqual(sharedSecret, sharedSecret2); + + var sharedSecret3 = HybridKemGenerator.Decapsulate(privKey2, ciphertext); + Assert.AreEqual(sharedSecret, sharedSecret3); + + // encapsulate + var newEncapsulation = HybridKemGenerator.Encapsulate(pubKey); + + // decapsulate + var newSharedSecret = HybridKemGenerator.Decapsulate(privKey, newEncapsulation.GetEncapsulation()); + Assert.AreEqual(newEncapsulation.GetSecret(), newSharedSecret); + + Console.WriteLine($"success: {hybridName}"); + } + } + } } } diff --git a/crypto/test/src/util/test/SimpleTest.cs b/crypto/test/src/util/test/SimpleTest.cs index d091e0cd3..5ad1ee1d4 100644 --- a/crypto/test/src/util/test/SimpleTest.cs +++ b/crypto/test/src/util/test/SimpleTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Reflection; using Org.BouncyCastle.Utilities.IO; @@ -156,5 +157,14 @@ internal static Stream FindTestResource(string homeDir, string fileName) return File.OpenRead(Path.Combine(dataDir.FullName, homeDir + separator + fileName)); } + + public static bool TestDataDirectoryExists(string name) + { + string fullName = GetFullName(name); + + var result = new List(); + string[] fullNames = GetAssembly().GetManifestResourceNames(); + return fullNames.Any((resource) => resource.StartsWith(fullName)); + } } } From a4af7825685b3f8a9e4ede88868d67238671253a Mon Sep 17 00:00:00 2001 From: Bence Mali Date: Fri, 13 Sep 2024 15:23:26 +0200 Subject: [PATCH 08/10] signature gen/verify fixes --- .../generators/HybridSignatureGenerator.cs | 118 +++++++++++------- crypto/test/src/crypto/test/PQCHybridTest.cs | 63 ++++++++++ 2 files changed, 135 insertions(+), 46 deletions(-) diff --git a/crypto/src/crypto/generators/HybridSignatureGenerator.cs b/crypto/src/crypto/generators/HybridSignatureGenerator.cs index 97a4b8b03..858a646c6 100644 --- a/crypto/src/crypto/generators/HybridSignatureGenerator.cs +++ b/crypto/src/crypto/generators/HybridSignatureGenerator.cs @@ -18,6 +18,7 @@ using System.Text; using System.Threading.Tasks; using Org.BouncyCastle.Math; +using Org.BouncyCastle.Crypto.Digests; namespace Org.BouncyCastle.crypto.generators { @@ -121,11 +122,10 @@ public static byte[] GenerateSignature(AsymmetricKeyParameter privKey, byte[] me byte[] classicalSignature = null; if (hybridPrivKey.Classical is ECPrivateKeyParameters ecPrivKey) { - var signer = new ECDsaSigner(); + var signer = new DsaDigestSigner(new ECDsaSigner(), new Sha512Digest()); signer.Init(true, ecPrivKey); - var signature = signer.GenerateSignature(message); - var encoding = new PlainDsaEncoding(); - classicalSignature = encoding.Encode(ecPrivKey.Parameters.N, signature[0], signature[1]); + signer.BlockUpdate(message, 0, message.Length); + classicalSignature = signer.GenerateSignature(); } else if (hybridPrivKey.Classical is Ed25519PrivateKeyParameters ed25519PrivKey) { @@ -183,77 +183,103 @@ public static bool VerifySignature(AsymmetricKeyParameter pubKey, byte[] message var hybridPubKey = pubKey as HybridKeyParameters; + var postQuantumSignatureSize = 0; + if (hybridPubKey.PostQuantum is DilithiumPublicKeyParameters mldsaKey) + { + switch (mldsaKey.Parameters.Name) + { + case "dilithium2": + postQuantumSignatureSize = 2420; + break; + case "dilithium3": + postQuantumSignatureSize = 3309; + break; + case "dilithium5": + postQuantumSignatureSize = 4627; + break; + } + } + else if (hybridPubKey.PostQuantum is SphincsPlusPublicKeyParameters slhdsaKey) + { + switch (slhdsaKey.Parameters.Name) + { + case "sha2-128f-simple": + case "shake-128f-simple": + postQuantumSignatureSize = 17088; + break; + case "sha2-128s-simple": + case "shake-128s-simple": + postQuantumSignatureSize = 7856; + break; + case "sha2-192f-simple": + case "shake-192f-simple": + postQuantumSignatureSize = 35664; + break; + case "sha2-192s-simple": + case "shake-192s-simple": + postQuantumSignatureSize = 16224; + break; + case "sha2-256f-simple": + case "shake-256f-simple": + postQuantumSignatureSize = 49856; + break; + case "sha2-256s-simple": + case "shake-256s-simple": + postQuantumSignatureSize = 29792; + break; + } + } + + if (postQuantumSignatureSize == 0) + { + throw new Exception("Post-quantum keytype not supported"); + } + + if (signature.Length <= postQuantumSignatureSize) + { + throw new Exception("Signature has wrong size"); + } + + var classicalSignature = signature.Take(signature.Length - postQuantumSignatureSize).ToArray(); + var postQuantumSignature = signature.Skip(signature.Length - postQuantumSignatureSize).ToArray(); + bool classicalVerified = false; if (hybridPubKey.Classical is ECPublicKeyParameters ecPublicKey) { var domainParameters = ecPublicKey.Parameters; var classicalSignatureLength = BigIntegers.GetUnsignedByteLength(domainParameters.N) * 2; - if (signature.Length <= classicalSignatureLength) - { - throw new Exception("Wrong size signature"); - } - - var encoding = new PlainDsaEncoding(); - var classicalSignature = encoding.Decode(domainParameters.N, signature.Take(classicalSignatureLength).ToArray()); - - var verifier = new ECDsaSigner(); + var verifier = new DsaDigestSigner(new ECDsaSigner(), new Sha512Digest()); verifier.Init(false, hybridPubKey.Classical); - if(!verifier.VerifySignature(message, classicalSignature[0], classicalSignature[1])) + verifier.BlockUpdate(message, 0, message.Length); + + if(!verifier.VerifySignature(classicalSignature)) { throw new VerificationException("Signature verification failed"); } - // take away classical signature - signature = signature.Skip(classicalSignatureLength).ToArray(); - classicalVerified = true; } else if (hybridPubKey.Classical is Ed25519PublicKeyParameters ed25519PublicKey) { - var classicalSignatureLength = Ed25519.SignatureSize; - - if (signature.Length <= classicalSignatureLength) - { - throw new Exception("Wrong size signature"); - } - - var classicalSignatureBytes = signature.Take(classicalSignatureLength).ToArray(); - var verifier = new Ed25519Signer(); verifier.Init(true, ed25519PublicKey); verifier.BlockUpdate(message, 0, message.Length); - if(!verifier.VerifySignature(signature)) + if(!verifier.VerifySignature(classicalSignature)) { throw new VerificationException("Signature verification failed"); } - - // take away classical signature - signature = signature.Skip(classicalSignatureLength).ToArray(); - classicalVerified = true; } else if (hybridPubKey.Classical is Ed448PublicKeyParameters ed448PublicKey) { - var classicalSignatureLength = Ed448.SignatureSize; - - if (signature.Length <= classicalSignatureLength) - { - throw new Exception("Wrong size signature"); - } - - var classicalSignatureBytes = signature.Take(classicalSignatureLength).ToArray(); - var verifier = new Ed448Signer(message); verifier.Init(true, ed448PublicKey); - if(!verifier.VerifySignature(signature)) + if(!verifier.VerifySignature(classicalSignature)) { throw new VerificationException("Signature verification failed"); } - // take away classical signature - signature = signature.Skip(classicalSignatureLength).ToArray(); - classicalVerified = true; } else if (hybridPubKey.Classical is RsaKeyParameters) @@ -272,7 +298,7 @@ public static bool VerifySignature(AsymmetricKeyParameter pubKey, byte[] message { var verifier = new DilithiumSigner(); verifier.Init(false, hybridPubKey.PostQuantum); - if (!verifier.VerifySignature(message, signature)) + if (!verifier.VerifySignature(message, postQuantumSignature)) { throw new VerificationException("Signature verification failed"); } @@ -283,7 +309,7 @@ public static bool VerifySignature(AsymmetricKeyParameter pubKey, byte[] message { var verifier = new SphincsPlusSigner(); verifier.Init(false, hybridPubKey.PostQuantum); - if (!verifier.VerifySignature(message, signature)) + if (!verifier.VerifySignature(message, postQuantumSignature)) { throw new VerificationException("Signature verification failed"); } diff --git a/crypto/test/src/crypto/test/PQCHybridTest.cs b/crypto/test/src/crypto/test/PQCHybridTest.cs index 6bf0039ca..fdd715b02 100644 --- a/crypto/test/src/crypto/test/PQCHybridTest.cs +++ b/crypto/test/src/crypto/test/PQCHybridTest.cs @@ -263,5 +263,68 @@ private static void TestKemInteropWith(string libraryName) } } } + + private static void TestSignatureInteropWith(string libraryName) + { + foreach (var postQuantum in postQuantumSignatures) + { + foreach (var classical in classicalSignatures) + { + var hybridName = $"{classical}_{postQuantum}"; + + AsymmetricKeyParameter privKey = null; + AsymmetricKeyParameter pubKey = null; + byte[] message = null; + byte[] signature = null; + + var directoryName = "hybrid." + libraryName + ".signature." + hybridName; + + if (!SimpleTest.TestDataDirectoryExists(directoryName)) + continue; + + using (var sr = new StringReader(System.Text.Encoding.ASCII.GetString(SimpleTest.GetTestData(directoryName + ".privkey.pem")))) + { + var reader = new PemReader(sr); + privKey = (HybridKeyParameters)reader.ReadObject(); + } + + using (var sr = new StringReader(System.Text.Encoding.ASCII.GetString(SimpleTest.GetTestData(directoryName + ".pubkey.pem")))) + { + var reader = new PemReader(sr); + pubKey = (HybridKeyParameters)reader.ReadObject(); + } + + using (var sr = new StringReader(System.Text.Encoding.ASCII.GetString(SimpleTest.GetTestData(directoryName + ".message.base64.txt").Skip(3).ToArray()))) + { + message = Convert.FromBase64String(sr.ReadToEnd()); + } + + using (var sr = new StringReader(System.Text.Encoding.ASCII.GetString(SimpleTest.GetTestData(directoryName + ".signature.base64.txt").Skip(3).ToArray()))) + { + signature = Convert.FromBase64String(sr.ReadToEnd()); + } + + var pubKey2 = PublicTryEnDecode(pubKey); + + var privKey2 = PrivateTryEnDecode(privKey); + + // verify deserialized signature + Assert.IsTrue(HybridSignatureGenerator.VerifySignature(pubKey, message, signature)); + Assert.IsTrue(HybridSignatureGenerator.VerifySignature(pubKey2, message, signature)); + + // sign with deserialized private key + var message2 = new byte[64]; + Random.NextBytes(message2); + var signature2 = HybridSignatureGenerator.GenerateSignature(privKey, message2); + var signature3 = HybridSignatureGenerator.GenerateSignature(privKey2, message2); + + // verify with deserialized public key + Assert.IsTrue(HybridSignatureGenerator.VerifySignature(pubKey, message2, signature2)); + Assert.IsTrue(HybridSignatureGenerator.VerifySignature(pubKey, message2, signature3)); + + Console.WriteLine($"success: {hybridName}"); + } + } + } } } From 6e64e668e54ff487b44700904fe463ada0cf9009 Mon Sep 17 00:00:00 2001 From: Bence Mali Date: Fri, 13 Sep 2024 15:46:31 +0200 Subject: [PATCH 09/10] dilithium to ml-dsa rename --- .../generators/HybridSignatureGenerator.cs | 27 ++++++++++--------- .../HybridKeyGenerationParameters.cs | 7 +++-- .../crypto/parameters/HybridKeyParameters.cs | 5 ++-- crypto/src/pkcs/PrivateKeyInfoFactory.cs | 3 +-- crypto/src/security/PrivateKeyFactory.cs | 23 +++++++--------- crypto/src/security/PublicKeyFactory.cs | 21 +++++++-------- .../src/x509/SubjectPublicKeyInfoFactory.cs | 3 +-- 7 files changed, 41 insertions(+), 48 deletions(-) diff --git a/crypto/src/crypto/generators/HybridSignatureGenerator.cs b/crypto/src/crypto/generators/HybridSignatureGenerator.cs index 858a646c6..a444f9bb1 100644 --- a/crypto/src/crypto/generators/HybridSignatureGenerator.cs +++ b/crypto/src/crypto/generators/HybridSignatureGenerator.cs @@ -6,7 +6,6 @@ using Org.BouncyCastle.Math.EC; using Org.BouncyCastle.Math.EC.Rfc8032; using Org.BouncyCastle.Pqc.Crypto; -using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Security; using Org.BouncyCastle.Tls.Crypto.Impl.BC; @@ -85,9 +84,9 @@ public AsymmetricCipherKeyPair GenerateKeyPair() } AsymmetricCipherKeyPair postQuantumKeypair = null; - if (parameters.PostQuantumParameters is DilithiumKeyGenerationParameters) + if (parameters.PostQuantumParameters is MLDsaKeyGenerationParameters) { - var generator = new DilithiumKeyPairGenerator(); + var generator = new MLDsaKeyPairGenerator(); generator.Init(parameters.PostQuantumParameters); postQuantumKeypair = generator.GenerateKeyPair(); } @@ -153,11 +152,12 @@ public static byte[] GenerateSignature(AsymmetricKeyParameter privKey, byte[] me } byte[] postQuantumSignature = null; - if (hybridPrivKey.PostQuantum is DilithiumKeyParameters) + if (hybridPrivKey.PostQuantum is MLDsaKeyParameters) { - var signer = new DilithiumSigner(); + var signer = new MLDsaSigner(); signer.Init(true, hybridPrivKey.PostQuantum); - postQuantumSignature = signer.GenerateSignature(message); + signer.BlockUpdate(message, 0, message.Length); + postQuantumSignature = signer.GenerateSignature(); } else if (hybridPrivKey.PostQuantum is SphincsPlusKeyParameters) { @@ -184,17 +184,17 @@ public static bool VerifySignature(AsymmetricKeyParameter pubKey, byte[] message var hybridPubKey = pubKey as HybridKeyParameters; var postQuantumSignatureSize = 0; - if (hybridPubKey.PostQuantum is DilithiumPublicKeyParameters mldsaKey) + if (hybridPubKey.PostQuantum is MLDsaKeyParameters mldsaKey) { switch (mldsaKey.Parameters.Name) { - case "dilithium2": + case "ML-DSA-44": postQuantumSignatureSize = 2420; break; - case "dilithium3": + case "ML-DSA-65": postQuantumSignatureSize = 3309; break; - case "dilithium5": + case "ML-DSA-87": postQuantumSignatureSize = 4627; break; } @@ -294,11 +294,12 @@ public static bool VerifySignature(AsymmetricKeyParameter pubKey, byte[] message } bool postQuantumVerified = false; - if (hybridPubKey.PostQuantum is DilithiumPublicKeyParameters) + if (hybridPubKey.PostQuantum is MLDsaKeyParameters) { - var verifier = new DilithiumSigner(); + var verifier = new MLDsaSigner(); verifier.Init(false, hybridPubKey.PostQuantum); - if (!verifier.VerifySignature(message, postQuantumSignature)) + verifier.BlockUpdate(message, 0, message.Length); + if (!verifier.VerifySignature(postQuantumSignature)) { throw new VerificationException("Signature verification failed"); } diff --git a/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs b/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs index 4270672f9..05454f92d 100644 --- a/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs +++ b/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs @@ -6,7 +6,6 @@ using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; using Org.BouncyCastle.Pqc.Crypto.MLKem; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Security; @@ -245,13 +244,13 @@ private void InitializeParameters() PostQuantumParameters = new MLKemKeyGenerationParameters(new Security.SecureRandom(), MLKemParameters.ML_KEM_1024); break; case "mldsa44": - PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium2); + PostQuantumParameters = new MLDsaKeyGenerationParameters(new Security.SecureRandom(), MLDsaParameters.ML_DSA_44); break; case "mldsa65": - PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium3); + PostQuantumParameters = new MLDsaKeyGenerationParameters(new Security.SecureRandom(), MLDsaParameters.ML_DSA_65); break; case "mldsa87": - PostQuantumParameters = new DilithiumKeyGenerationParameters(new Security.SecureRandom(), DilithiumParameters.Dilithium5); + PostQuantumParameters = new MLDsaKeyGenerationParameters(new Security.SecureRandom(), MLDsaParameters.ML_DSA_87); break; case "slhdsasha2128f": PostQuantumParameters = new SphincsPlusKeyGenerationParameters(new Security.SecureRandom(), SphincsPlusParameters.sha2_128f_simple); diff --git a/crypto/src/crypto/parameters/HybridKeyParameters.cs b/crypto/src/crypto/parameters/HybridKeyParameters.cs index c85582d11..76299ba8b 100644 --- a/crypto/src/crypto/parameters/HybridKeyParameters.cs +++ b/crypto/src/crypto/parameters/HybridKeyParameters.cs @@ -3,7 +3,6 @@ using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math.EC.Custom.Sec; using Org.BouncyCastle.Math.EC.Rfc7748; -using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; using Org.BouncyCastle.Pqc.Crypto.MLKem; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using System; @@ -100,9 +99,9 @@ public HybridKeyParameters(AsymmetricKeyParameter classical, AsymmetricKeyParame break; } } - else if (PostQuantum is DilithiumKeyParameters) + else if (PostQuantum is MLDsaKeyParameters) { - switch ((PostQuantum as DilithiumKeyParameters).Parameters.GetEngine(null).Mode) + switch ((PostQuantum as MLDsaKeyParameters).Parameters.GetEngine(null).Mode) { case 2: postQuantumCanonicalName = string.Concat("mldsa", $"{44}"); diff --git a/crypto/src/pkcs/PrivateKeyInfoFactory.cs b/crypto/src/pkcs/PrivateKeyInfoFactory.cs index de362a247..1a4ef6f09 100644 --- a/crypto/src/pkcs/PrivateKeyInfoFactory.cs +++ b/crypto/src/pkcs/PrivateKeyInfoFactory.cs @@ -17,7 +17,6 @@ using Org.BouncyCastle.Math.EC; using Org.BouncyCastle.Math.EC.Multiplier; using Org.BouncyCastle.Pqc.Asn1; -using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; using Org.BouncyCastle.Pqc.Crypto.MLKem; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Security; @@ -325,7 +324,7 @@ public static PrivateKeyInfo CreatePrivateKeyInfo(AsymmetricKeyParameter private case "mldsa44": case "mldsa65": case "mldsa87": - postQuantumBytes = (key.PostQuantum as DilithiumPrivateKeyParameters).GetEncoded(); + postQuantumBytes = (key.PostQuantum as MLDsaPrivateKeyParameters).GetEncoded(); break; case "slhdsasha2128f": case "slhdsasha2192f": diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs index 34cf5720a..bedbcc551 100644 --- a/crypto/src/security/PrivateKeyFactory.cs +++ b/crypto/src/security/PrivateKeyFactory.cs @@ -20,7 +20,6 @@ using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Math; using Org.BouncyCastle.Pkcs; -using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; using Org.BouncyCastle.Pqc.Crypto.MLKem; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Pqc.Crypto.Utilities; @@ -489,23 +488,23 @@ public static AsymmetricKeyParameter CreateKey( postQuantumKey = new MLKemPrivateKeyParameters(parameters, hybridBytes); } - else if (keyParameters.PostQuantumParameters is DilithiumKeyGenerationParameters dilithiumParameters) + else if (keyParameters.PostQuantumParameters is MLDsaKeyGenerationParameters mldsaParameters) { int postQuantumKeySize = 0; - DilithiumParameters parameters; - switch (dilithiumParameters.Parameters.Name) + MLDsaParameters parameters; + switch (mldsaParameters.Parameters.Name) { - case "dilithium2": + case "ML-DSA-44": postQuantumKeySize = 2560; - parameters = DilithiumParameters.Dilithium2; + parameters = MLDsaParameters.ML_DSA_44; break; - case "dilithium3": + case "ML-DSA-65": postQuantumKeySize = 4032; - parameters = DilithiumParameters.Dilithium3; + parameters = MLDsaParameters.ML_DSA_65; break; - case "dilithium5": + case "ML-DSA-87": postQuantumKeySize = 4896; - parameters = DilithiumParameters.Dilithium5; + parameters = MLDsaParameters.ML_DSA_87; break; default: throw new Exception("Post-quantum keytype not supported"); @@ -516,9 +515,7 @@ public static AsymmetricKeyParameter CreateKey( throw new Exception("Encoded hybrid private key has wrong size"); } - var publicParams = new DilithiumPublicKeyParameters(parameters, hybridBytes); - - postQuantumKey = new DilithiumPrivateKeyParameters(parameters, hybridBytes, publicParams); + postQuantumKey = new MLDsaPrivateKeyParameters(parameters, hybridBytes); } else if (keyParameters.PostQuantumParameters is SphincsPlusKeyGenerationParameters sphincsParameters) { diff --git a/crypto/src/security/PublicKeyFactory.cs b/crypto/src/security/PublicKeyFactory.cs index ee2433b23..00c05bd36 100644 --- a/crypto/src/security/PublicKeyFactory.cs +++ b/crypto/src/security/PublicKeyFactory.cs @@ -19,7 +19,6 @@ using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; -using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; using Org.BouncyCastle.Pqc.Crypto.MLKem; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Pqc.Crypto.Utilities; @@ -392,23 +391,23 @@ public static AsymmetricKeyParameter CreateKey( postQuantumKey = new MLKemPublicKeyParameters(parameters, hybridBytes); } - else if (keyParameters.PostQuantumParameters is DilithiumKeyGenerationParameters dilithiumParameters) + else if (keyParameters.PostQuantumParameters is MLDsaKeyGenerationParameters mldsaParameters) { int postQuantumKeySize = 0; - DilithiumParameters parameters; - switch (dilithiumParameters.Parameters.Name) + MLDsaParameters parameters; + switch (mldsaParameters.Parameters.Name) { - case "dilithium2": + case "ML-DSA-44": postQuantumKeySize = 1312; - parameters = DilithiumParameters.Dilithium2; + parameters = MLDsaParameters.ML_DSA_44; break; - case "dilithium3": + case "ML-DSA-65": postQuantumKeySize = 1952; - parameters = DilithiumParameters.Dilithium3; + parameters = MLDsaParameters.ML_DSA_65; break; - case "dilithium5": + case "ML-DSA-87": postQuantumKeySize = 2592; - parameters = DilithiumParameters.Dilithium5; + parameters = MLDsaParameters.ML_DSA_87; break; default: throw new Exception("Post-quantum keytype not supported"); @@ -419,7 +418,7 @@ public static AsymmetricKeyParameter CreateKey( throw new Exception("Encoded hybrid public key has wrong size"); } - postQuantumKey = new DilithiumPublicKeyParameters(parameters, hybridBytes); + postQuantumKey = new MLDsaPublicKeyParameters(parameters, hybridBytes); } else if (keyParameters.PostQuantumParameters is SphincsPlusKeyGenerationParameters sphincsParameters) { diff --git a/crypto/src/x509/SubjectPublicKeyInfoFactory.cs b/crypto/src/x509/SubjectPublicKeyInfoFactory.cs index 93fc800e6..d5f17cb40 100644 --- a/crypto/src/x509/SubjectPublicKeyInfoFactory.cs +++ b/crypto/src/x509/SubjectPublicKeyInfoFactory.cs @@ -15,7 +15,6 @@ using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; using Org.BouncyCastle.Pqc.Crypto.MLKem; -using Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Utilities; @@ -306,7 +305,7 @@ public static SubjectPublicKeyInfo CreateSubjectPublicKeyInfo( case "mldsa44": case "mldsa65": case "mldsa87": - postQuantumBytes = (key.PostQuantum as DilithiumPublicKeyParameters).GetEncoded(); + postQuantumBytes = (key.PostQuantum as MLDsaPublicKeyParameters).GetEncoded(); break; case "slhdsasha2128f": case "slhdsasha2192f": From cc0431627fd1b314bf565b6dd257fa84fd2d6cb9 Mon Sep 17 00:00:00 2001 From: Bence Mali Date: Tue, 17 Sep 2024 13:59:08 +0200 Subject: [PATCH 10/10] signature hybridization fixes --- .../generators/HybridSignatureGenerator.cs | 29 +++++--- .../HybridKeyGenerationParameters.cs | 72 +++++++++---------- 2 files changed, 57 insertions(+), 44 deletions(-) diff --git a/crypto/src/crypto/generators/HybridSignatureGenerator.cs b/crypto/src/crypto/generators/HybridSignatureGenerator.cs index a444f9bb1..e37f9ff90 100644 --- a/crypto/src/crypto/generators/HybridSignatureGenerator.cs +++ b/crypto/src/crypto/generators/HybridSignatureGenerator.cs @@ -18,6 +18,7 @@ using System.Threading.Tasks; using Org.BouncyCastle.Math; using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.crypto.generators { @@ -171,7 +172,9 @@ public static byte[] GenerateSignature(AsymmetricKeyParameter privKey, byte[] me throw new Exception("Post-quantum keytype not supported"); } - return Arrays.Concatenate(classicalSignature, postQuantumSignature); + var encodedLength = Pack.UInt32_To_BE(Convert.ToUInt32(classicalSignature.Length)); + + return encodedLength.Concat(classicalSignature).Concat(postQuantumSignature).ToArray(); } public static bool VerifySignature(AsymmetricKeyParameter pubKey, byte[] message, byte[] signature) @@ -235,25 +238,35 @@ public static bool VerifySignature(AsymmetricKeyParameter pubKey, byte[] message throw new Exception("Post-quantum keytype not supported"); } - if (signature.Length <= postQuantumSignatureSize) + if (signature.Length <= (4 + postQuantumSignatureSize)) { throw new Exception("Signature has wrong size"); } - var classicalSignature = signature.Take(signature.Length - postQuantumSignatureSize).ToArray(); - var postQuantumSignature = signature.Skip(signature.Length - postQuantumSignatureSize).ToArray(); + var classicalSignatureSpace = signature.Length - 4 - postQuantumSignatureSize; + var encodedLengthBytes = signature.Take(4).ToArray(); + var classicalSignature = signature.Skip(4).Take(classicalSignatureSpace).ToArray(); + var postQuantumSignature = signature.Skip(4 + classicalSignatureSpace).Take(postQuantumSignatureSize).ToArray(); bool classicalVerified = false; if (hybridPubKey.Classical is ECPublicKeyParameters ecPublicKey) { var domainParameters = ecPublicKey.Parameters; - var classicalSignatureLength = BigIntegers.GetUnsignedByteLength(domainParameters.N) * 2; + var encodedLength = Convert.ToInt32(Pack.BE_To_UInt32(encodedLengthBytes)); + + if (encodedLength > classicalSignature.Length) + { + throw new Exception("Incorrect signature encoding"); + } + + var actualSignature = classicalSignature.Take(encodedLength).ToArray(); var verifier = new DsaDigestSigner(new ECDsaSigner(), new Sha512Digest()); verifier.Init(false, hybridPubKey.Classical); verifier.BlockUpdate(message, 0, message.Length); + var valami = verifier.GetMaxSignatureSize(); - if(!verifier.VerifySignature(classicalSignature)) + if (!verifier.VerifySignature(actualSignature)) { throw new VerificationException("Signature verification failed"); } @@ -265,7 +278,7 @@ public static bool VerifySignature(AsymmetricKeyParameter pubKey, byte[] message var verifier = new Ed25519Signer(); verifier.Init(true, ed25519PublicKey); verifier.BlockUpdate(message, 0, message.Length); - if(!verifier.VerifySignature(classicalSignature)) + if (!verifier.VerifySignature(classicalSignature)) { throw new VerificationException("Signature verification failed"); } @@ -275,7 +288,7 @@ public static bool VerifySignature(AsymmetricKeyParameter pubKey, byte[] message { var verifier = new Ed448Signer(message); verifier.Init(true, ed448PublicKey); - if(!verifier.VerifySignature(classicalSignature)) + if (!verifier.VerifySignature(classicalSignature)) { throw new VerificationException("Signature verification failed"); } diff --git a/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs b/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs index 05454f92d..9c194ca9b 100644 --- a/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs +++ b/crypto/src/crypto/parameters/HybridKeyGenerationParameters.cs @@ -44,46 +44,46 @@ public class HybridKeyGenerationParameters public Dictionary postQuantumNameToOid = new Dictionary() { - { "mlkem512", NistObjectIdentifiers.IdAlgMLKem512 }, - { "mlkem768", NistObjectIdentifiers.IdAlgMLKem768 }, - { "mlkem1024", NistObjectIdentifiers.IdAlgMLKem1024 }, - { "mldsa44", NistObjectIdentifiers.IdHashMLDsa44WithSha512 }, - { "mldsa65", NistObjectIdentifiers.IdHashMLDsa65WithSha512 }, - { "mldsa87", NistObjectIdentifiers.IdHashMLDsa87WithSha512 }, - { "slhdsasha2128f", NistObjectIdentifiers.IdHashSlhDsasha2_128fWithSha256 }, - { "slhdsasha2192f", NistObjectIdentifiers.IdHashSlhDsasha2_192fWithSha512 }, - { "slhdsasha2256f", NistObjectIdentifiers.IdHashSlhDsasha2_256fWithSha512 }, - { "slhdsasha2128s", NistObjectIdentifiers.IdHashSlhDsaSha2_128sWithSha256 }, - { "slhdsasha2192s", NistObjectIdentifiers.IdHashSlhDsasha2_192sWithSha512 }, - { "slhdsasha2256s", NistObjectIdentifiers.IdHashSlhDsasha2_256sWithSha512 }, - { "slhdsashake128f", NistObjectIdentifiers.IdHashSlhDsashake_128fWithShake128 }, - { "slhdsashake192f", NistObjectIdentifiers.IdHashSlhDsashake_192fWithShake256 }, - { "slhdsashake256f", NistObjectIdentifiers.IdHashSlhDsashake_256fWithShake256 }, - { "slhdsashake128s", NistObjectIdentifiers.IdHashSlhDsashake_128sWithShake128 }, - { "slhdsashake192s", NistObjectIdentifiers.IdHashSlhDsashake_192sWithShake256 }, - { "slhdsashake256s", NistObjectIdentifiers.IdHashSlhDsashake_256sWithShake256 }, + { "mlkem512", NistObjectIdentifiers.id_alg_ml_kem_512 }, + { "mlkem768", NistObjectIdentifiers.id_alg_ml_kem_768 }, + { "mlkem1024", NistObjectIdentifiers.id_alg_ml_kem_1024 }, + { "mldsa44", NistObjectIdentifiers.id_hash_ml_dsa_44_with_sha512 }, + { "mldsa65", NistObjectIdentifiers.id_hash_ml_dsa_65_with_sha512 }, + { "mldsa87", NistObjectIdentifiers.id_hash_ml_dsa_87_with_sha512 }, + { "slhdsasha2128f", NistObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256 }, + { "slhdsasha2192f", NistObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512 }, + { "slhdsasha2256f", NistObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512 }, + { "slhdsasha2128s", NistObjectIdentifiers.id_hash_slh_dsa_sha2_128s_with_sha256 }, + { "slhdsasha2192s", NistObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512 }, + { "slhdsasha2256s", NistObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512 }, + { "slhdsashake128f", NistObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128 }, + { "slhdsashake192f", NistObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256 }, + { "slhdsashake256f", NistObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256 }, + { "slhdsashake128s", NistObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128 }, + { "slhdsashake192s", NistObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256 }, + { "slhdsashake256s", NistObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256 }, }; public Dictionary postQuantumOidToName = new Dictionary() { - { NistObjectIdentifiers.IdAlgMLKem512, "mlkem512" }, - { NistObjectIdentifiers.IdAlgMLKem768 , "mlkem768" }, - { NistObjectIdentifiers.IdAlgMLKem1024 , "mlkem1024" }, - { NistObjectIdentifiers.IdHashMLDsa44WithSha512 , "mldsa44" }, - { NistObjectIdentifiers.IdHashMLDsa65WithSha512 , "mldsa65" }, - { NistObjectIdentifiers.IdHashMLDsa87WithSha512 , "mldsa87" }, - { NistObjectIdentifiers.IdHashSlhDsasha2_128fWithSha256 , "slhdsasha2128f" }, - { NistObjectIdentifiers.IdHashSlhDsasha2_192fWithSha512 , "slhdsasha2192f" }, - { NistObjectIdentifiers.IdHashSlhDsasha2_256fWithSha512 , "slhdsasha2256f" }, - { NistObjectIdentifiers.IdHashSlhDsaSha2_128sWithSha256 , "slhdsasha2128s" }, - { NistObjectIdentifiers.IdHashSlhDsasha2_192sWithSha512 , "slhdsasha2192s" }, - { NistObjectIdentifiers.IdHashSlhDsasha2_256sWithSha512 , "slhdsasha2256s" }, - { NistObjectIdentifiers.IdHashSlhDsashake_128fWithShake128 , "slhdsashake128f" }, - { NistObjectIdentifiers.IdHashSlhDsashake_192fWithShake256 , "slhdsashake192f" }, - { NistObjectIdentifiers.IdHashSlhDsashake_256fWithShake256 , "slhdsashake256f" }, - { NistObjectIdentifiers.IdHashSlhDsashake_128sWithShake128 , "slhdsashake128s" }, - { NistObjectIdentifiers.IdHashSlhDsashake_192sWithShake256 , "slhdsashake192s" }, - { NistObjectIdentifiers.IdHashSlhDsashake_256sWithShake256 , "slhdsashake256s" }, + { NistObjectIdentifiers.id_alg_ml_kem_512, "mlkem512" }, + { NistObjectIdentifiers.id_alg_ml_kem_768 , "mlkem768" }, + { NistObjectIdentifiers.id_alg_ml_kem_1024 , "mlkem1024" }, + { NistObjectIdentifiers.id_hash_ml_dsa_44_with_sha512 , "mldsa44" }, + { NistObjectIdentifiers.id_hash_ml_dsa_65_with_sha512 , "mldsa65" }, + { NistObjectIdentifiers.id_hash_ml_dsa_87_with_sha512 , "mldsa87" }, + { NistObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256 , "slhdsasha2128f" }, + { NistObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512 , "slhdsasha2192f" }, + { NistObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512 , "slhdsasha2256f" }, + { NistObjectIdentifiers.id_hash_slh_dsa_sha2_128s_with_sha256 , "slhdsasha2128s" }, + { NistObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512 , "slhdsasha2192s" }, + { NistObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512 , "slhdsasha2256s" }, + { NistObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128 , "slhdsashake128f" }, + { NistObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256 , "slhdsashake192f" }, + { NistObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256 , "slhdsashake256f" }, + { NistObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128 , "slhdsashake128s" }, + { NistObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256 , "slhdsashake192s" }, + { NistObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256 , "slhdsashake256s" }, }; public DerObjectIdentifier ClassicalAlgorithm { get; set; }