From 87084dd908557ec94f92f3f4dd224998a2da227c Mon Sep 17 00:00:00 2001 From: David Hook Date: Wed, 30 Aug 2023 17:43:49 +1000 Subject: updated SPHINCS+ private key encoding --- crypto/src/asn1/bc/BCObjectIdentifiers.cs | 2 ++ .../sphincsplus/SPHINCSPlusPrivateKeyParameters.cs | 4 ++-- .../src/pqc/crypto/utils/PqcPrivateKeyFactory.cs | 22 +++++++++++++++++----- .../pqc/crypto/utils/PqcPrivateKeyInfoFactory.cs | 6 +----- crypto/test/src/pqc/crypto/test/SphincsPlusTest.cs | 12 ++++++------ 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/crypto/src/asn1/bc/BCObjectIdentifiers.cs b/crypto/src/asn1/bc/BCObjectIdentifiers.cs index 451f846f8..e9d5efdc5 100644 --- a/crypto/src/asn1/bc/BCObjectIdentifiers.cs +++ b/crypto/src/asn1/bc/BCObjectIdentifiers.cs @@ -180,6 +180,8 @@ namespace Org.BouncyCastle.Asn1.BC public static readonly DerObjectIdentifier sphincsPlus_haraka_256f_r3_simple = sphincsPlus.Branch("36"); // Interop OIDs. + public static readonly DerObjectIdentifier sphincsPlus_interop = new DerObjectIdentifier("1.3.9999.6"); + public static readonly DerObjectIdentifier sphincsPlus_sha2_128f = new DerObjectIdentifier("1.3.9999.6.4.13"); public static readonly DerObjectIdentifier sphincsPlus_sha2_128s = new DerObjectIdentifier("1.3.9999.6.4.16"); public static readonly DerObjectIdentifier sphincsPlus_sha2_192f = new DerObjectIdentifier("1.3.9999.6.5.10"); diff --git a/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusPrivateKeyParameters.cs b/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusPrivateKeyParameters.cs index de9dae2ce..d9353fd4c 100644 --- a/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusPrivateKeyParameters.cs +++ b/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusPrivateKeyParameters.cs @@ -38,12 +38,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus public byte[] GetEncoded() { - return Arrays.ConcatenateAll(Parameters.GetEncoded(), m_sk.seed, m_sk.prf, m_pk.seed, m_pk.root); + return Arrays.ConcatenateAll(m_sk.seed, m_sk.prf, m_pk.seed, m_pk.root); } public byte[] GetEncodedPublicKey() { - return Arrays.ConcatenateAll(Parameters.GetEncoded(), m_pk.seed, m_pk.root); + return Arrays.ConcatenateAll(m_pk.seed, m_pk.root); } public byte[] GetPrf() diff --git a/crypto/src/pqc/crypto/utils/PqcPrivateKeyFactory.cs b/crypto/src/pqc/crypto/utils/PqcPrivateKeyFactory.cs index 8058ed695..1fc937e6f 100644 --- a/crypto/src/pqc/crypto/utils/PqcPrivateKeyFactory.cs +++ b/crypto/src/pqc/crypto/utils/PqcPrivateKeyFactory.cs @@ -86,14 +86,26 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities return new FrodoPrivateKeyParameters(spParams, keyEnc); } - if (algOid.On(BCObjectIdentifiers.sphincsPlus)) + if (algOid.On(BCObjectIdentifiers.sphincsPlus) || algOid.On(BCObjectIdentifiers.sphincsPlus_interop)) { - SphincsPlusPrivateKey spKey = SphincsPlusPrivateKey.GetInstance(keyInfo.ParsePrivateKey()); + Asn1Encodable obj = keyInfo.ParsePrivateKey(); SphincsPlusParameters spParams = PqcUtilities.SphincsPlusParamsLookup(algOid); - SphincsPlusPublicKey publicKey = spKey.PublicKey; - return new SphincsPlusPrivateKeyParameters(spParams, spKey.GetSkseed(), spKey.GetSkprf(), - publicKey.GetPkseed(), publicKey.GetPkroot()); + if (obj is Asn1Sequence keySeq) + { + SphincsPlusPrivateKey spKey = SphincsPlusPrivateKey.GetInstance(keySeq); + + SphincsPlusPublicKey publicKey = spKey.PublicKey; + + return new SphincsPlusPrivateKeyParameters(spParams, spKey.GetSkseed(), spKey.GetSkprf(), + publicKey.GetPkseed(), publicKey.GetPkroot()); + } + else + { + Asn1OctetString oct = Asn1OctetString.GetInstance(obj); + + return new SphincsPlusPrivateKeyParameters(spParams, oct.GetOctets()); + } } if (algOid.On(BCObjectIdentifiers.pqc_kem_saber)) { diff --git a/crypto/src/pqc/crypto/utils/PqcPrivateKeyInfoFactory.cs b/crypto/src/pqc/crypto/utils/PqcPrivateKeyInfoFactory.cs index 1895bf891..4be386ed4 100644 --- a/crypto/src/pqc/crypto/utils/PqcPrivateKeyInfoFactory.cs +++ b/crypto/src/pqc/crypto/utils/PqcPrivateKeyInfoFactory.cs @@ -60,12 +60,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities { AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( PqcUtilities.SphincsPlusOidLookup(sphincsPlusPrivateKeyParameters.Parameters)); - SphincsPlusPublicKey spPub = new SphincsPlusPublicKey(sphincsPlusPrivateKeyParameters.GetPublicSeed(), - sphincsPlusPrivateKeyParameters.GetRoot()); - SphincsPlusPrivateKey spPriv = new SphincsPlusPrivateKey(0, sphincsPlusPrivateKeyParameters.GetSeed(), - sphincsPlusPrivateKeyParameters.GetPrf(), spPub); - return new PrivateKeyInfo(algorithmIdentifier, spPriv, attributes); + return new PrivateKeyInfo(algorithmIdentifier, new DerOctetString(sphincsPlusPrivateKeyParameters.GetEncoded()), attributes); } if (privateKey is CmcePrivateKeyParameters cmcePrivateKeyParameters) { diff --git a/crypto/test/src/pqc/crypto/test/SphincsPlusTest.cs b/crypto/test/src/pqc/crypto/test/SphincsPlusTest.cs index 960c5d762..44b1578e2 100644 --- a/crypto/test/src/pqc/crypto/test/SphincsPlusTest.cs +++ b/crypto/test/src/pqc/crypto/test/SphincsPlusTest.cs @@ -77,7 +77,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests SphincsPlusPrivateKeyParameters privParams = (SphincsPlusPrivateKeyParameters)kp.Private; Assert.True(Arrays.AreEqual(Hex.Decode("3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5"), pubParams.GetEncoded())); - Assert.True(Arrays.AreEqual(Arrays.Concatenate(privParams.Parameters.GetEncoded(), Hex.Decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e4792f267aafa3f87ca60d01cb54f29202a3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5")), privParams.GetEncoded())); + Assert.True(Arrays.AreEqual(Hex.Decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e4792f267aafa3f87ca60d01cb54f29202a3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5"), privParams.GetEncoded())); SubjectPublicKeyInfo pubInfo = PqcSubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubParams); PrivateKeyInfo privInfo = PqcPrivateKeyInfoFactory.CreatePrivateKeyInfo(privParams); @@ -86,7 +86,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests privParams = (SphincsPlusPrivateKeyParameters)PqcPrivateKeyFactory.CreateKey(privInfo.GetEncoded()); Assert.True(Arrays.AreEqual(Hex.Decode("3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5"), pubParams.GetEncoded())); - Assert.True(Arrays.AreEqual(Arrays.Concatenate(privParams.Parameters.GetEncoded(), Hex.Decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e4792f267aafa3f87ca60d01cb54f29202a3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5")), privParams.GetEncoded())); + Assert.True(Arrays.AreEqual(Hex.Decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e4792f267aafa3f87ca60d01cb54f29202a3e784ccb7ebcdcfd45542b7f6af778742e0f4479175084aa488b3b74340678aa6ba9430051e61cb676e8449087b938a79575b3a16736ce68a3655a28001155f5"), privParams.GetEncoded())); } [Test] @@ -96,7 +96,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests SphincsPlusPrivateKeyParameters privParams = new SphincsPlusPrivateKeyParameters(SphincsPlusParameters.sha2_128f, Hex.Decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8")); Assert.True(Arrays.AreEqual(Hex.Decode("b505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8"), pubParams.GetEncoded())); - Assert.True(Arrays.AreEqual(Arrays.Concatenate(privParams.Parameters.GetEncoded(), Hex.Decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8")), privParams.GetEncoded())); + Assert.True(Arrays.AreEqual(Hex.Decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e473985e5a31e5b9a0457916c84320c2ea8"), privParams.GetEncoded())); byte[] msg = Hex.Decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8"); @@ -210,7 +210,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests SphincsPlusPrivateKeyParameters privParams = (SphincsPlusPrivateKeyParameters)kp.Private; Assert.True(Arrays.AreEqual(Hex.Decode("b505d7cfad1b497499323c8686325e47afbc007ba1e2b4a138f03aa9a6195ac8"), pubParams.GetEncoded())); - Assert.True(Arrays.AreEqual(Arrays.Concatenate(privParams.Parameters.GetEncoded(), Hex.Decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e47afbc007ba1e2b4a138f03aa9a6195ac8")), privParams.GetEncoded())); + Assert.True(Arrays.AreEqual(Hex.Decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e47afbc007ba1e2b4a138f03aa9a6195ac8"), privParams.GetEncoded())); } [Test] @@ -268,7 +268,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests SphincsPlusPrivateKeyParameters privParams = (SphincsPlusPrivateKeyParameters)kp.Private; Assert.True(Arrays.AreEqual(Hex.Decode("b505d7cfad1b497499323c8686325e4714be46e5b92237d09a0ea8a0404033a6"), pubParams.GetEncoded())); - Assert.True(Arrays.AreEqual(Arrays.Concatenate(privParams.Parameters.GetEncoded(), Hex.Decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e4714be46e5b92237d09a0ea8a0404033a6")), privParams.GetEncoded())); + Assert.True(Arrays.AreEqual(Hex.Decode("7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2db505d7cfad1b497499323c8686325e4714be46e5b92237d09a0ea8a0404033a6"), privParams.GetEncoded())); } [Test] @@ -423,7 +423,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests } Assert.True(Arrays.AreEqual(pk, pubParams.GetEncoded()), name + " " + count + ": public key"); - Assert.True(Arrays.AreEqual(Arrays.Concatenate(privParams.Parameters.GetEncoded(), sk), privParams.GetEncoded()), name + " " + count + ": secret key"); + Assert.True(Arrays.AreEqual(sk, privParams.GetEncoded()), name + " " + count + ": secret key"); // // Signature test -- cgit 1.4.1