diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-04-18 22:04:16 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-04-18 22:04:16 +0700 |
commit | 60cd331972c01dc7c5e0d78de67c5fcc8bf2b007 (patch) | |
tree | 3e9893020957d9bc12785a55f257296e8b869551 | |
parent | Remove unused variable (diff) | |
download | BouncyCastle.NET-ed25519-60cd331972c01dc7c5e0d78de67c5fcc8bf2b007.tar.xz |
Update Kyber public key encoding
-rw-r--r-- | crypto/src/pqc/asn1/KyberPublicKey.cs | 60 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/utils/PqcPublicKeyFactory.cs | 40 | ||||
-rw-r--r-- | crypto/src/pqc/crypto/utils/PqcSubjectPublicKeyInfoFactory.cs | 6 |
3 files changed, 81 insertions, 25 deletions
diff --git a/crypto/src/pqc/asn1/KyberPublicKey.cs b/crypto/src/pqc/asn1/KyberPublicKey.cs new file mode 100644 index 000000000..9f162e334 --- /dev/null +++ b/crypto/src/pqc/asn1/KyberPublicKey.cs @@ -0,0 +1,60 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Pqc.Asn1 +{ + /** + * Crystal Kyber Public Key Format. + * See https://www.ietf.org/archive/id/draft-uni-qsckeys-kyber-00.html for details. + * <pre> + * KyberPublicKey ::= SEQUENCE { + * t OCTET STRING, + * rho OCTET STRING + * } + * </pre> + */ + [Obsolete("Will be removed as this draft proposal was rejected")] + public sealed class KyberPublicKey + : Asn1Encodable + { + public static KyberPublicKey GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is KyberPublicKey kyberPublicKey) + return kyberPublicKey; + return new KyberPublicKey(Asn1Sequence.GetInstance(obj)); + } + + public static KyberPublicKey GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + + private readonly byte[] m_t; + private readonly byte[] m_rho; + + public KyberPublicKey(byte[] t, byte[] rho) + { + m_t = t; + m_rho = rho; + } + + private KyberPublicKey(Asn1Sequence seq) + { + m_t = Arrays.Clone(Asn1OctetString.GetInstance(seq[0]).GetOctets()); + m_rho = Arrays.Clone(Asn1OctetString.GetInstance(seq[1]).GetOctets()); + } + + public byte[] T => Arrays.Clone(m_t); + + public byte[] Rho => Arrays.Clone(m_rho); + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(new DerOctetString(m_t), new DerOctetString(m_rho)); + } + } +} diff --git a/crypto/src/pqc/crypto/utils/PqcPublicKeyFactory.cs b/crypto/src/pqc/crypto/utils/PqcPublicKeyFactory.cs index 3c9849799..909b93577 100644 --- a/crypto/src/pqc/crypto/utils/PqcPublicKeyFactory.cs +++ b/crypto/src/pqc/crypto/utils/PqcPublicKeyFactory.cs @@ -21,6 +21,7 @@ using Org.BouncyCastle.Pqc.Crypto.Saber; using Org.BouncyCastle.Pqc.Crypto.Sike; using Org.BouncyCastle.Pqc.Crypto.SphincsPlus; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; namespace Org.BouncyCastle.Pqc.Crypto.Utilities { @@ -153,18 +154,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities /// <exception cref="IOException"> on an error decoding the key</exception> public static AsymmetricKeyParameter CreateKey(SubjectPublicKeyInfo keyInfo, object defaultParams) { - AlgorithmIdentifier algId = keyInfo.AlgorithmID; - SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter)Converters[algId.Algorithm]; + var algID = keyInfo.AlgorithmID; + var oid = algID.Algorithm; - if (converter != null) - { - return converter.GetPublicKeyParameters(keyInfo, defaultParams); - } - else - { - throw new IOException("algorithm identifier in public key not recognised: " + algId.Algorithm); - } + SubjectPublicKeyInfoConverter converter = CollectionUtilities.GetValueOrNull(Converters, oid) + ?? throw new IOException("algorithm identifier in public key not recognised: " + oid); + + return converter.GetPublicKeyParameters(keyInfo, defaultParams); } + private abstract class SubjectPublicKeyInfoConverter { internal abstract AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams); @@ -294,24 +292,24 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities private class KyberConverter : SubjectPublicKeyInfoConverter { - internal override AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, object defaultParams) + internal override AsymmetricKeyParameter GetPublicKeyParameters(SubjectPublicKeyInfo keyInfo, + object defaultParams) { KyberParameters kyberParameters = PqcUtilities.KyberParamsLookup(keyInfo.AlgorithmID.Algorithm); - Asn1Object obj = keyInfo.ParsePublicKey(); - if (obj is Asn1Sequence) + try { - Asn1Sequence keySeq = Asn1Sequence.GetInstance(obj); + Asn1Object obj = keyInfo.ParsePublicKey(); +#pragma warning disable CS0618 // Type or member is obsolete + KyberPublicKey kyberKey = KyberPublicKey.GetInstance(obj); +#pragma warning restore CS0618 // Type or member is obsolete - return new KyberPublicKeyParameters(kyberParameters, - Asn1OctetString.GetInstance(keySeq[0]).GetOctets(), - Asn1OctetString.GetInstance(keySeq[1]).GetOctets()); + return new KyberPublicKeyParameters(kyberParameters, kyberKey.T, kyberKey.Rho); } - else + catch (Exception) { - byte[] encKey = Asn1OctetString.GetInstance(obj).GetOctets(); - - return new KyberPublicKeyParameters(kyberParameters, encKey); + // we're a raw encoding + return new KyberPublicKeyParameters(kyberParameters, keyInfo.PublicKeyData.GetOctets()); } } } diff --git a/crypto/src/pqc/crypto/utils/PqcSubjectPublicKeyInfoFactory.cs b/crypto/src/pqc/crypto/utils/PqcSubjectPublicKeyInfoFactory.cs index 672108789..c13255c68 100644 --- a/crypto/src/pqc/crypto/utils/PqcSubjectPublicKeyInfoFactory.cs +++ b/crypto/src/pqc/crypto/utils/PqcSubjectPublicKeyInfoFactory.cs @@ -115,10 +115,8 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities { AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier( PqcUtilities.KyberOidLookup(kyberPublicKeyParameters.Parameters)); - Asn1EncodableVector v = new Asn1EncodableVector(2); - v.Add(new DerOctetString(kyberPublicKeyParameters.T)); - v.Add(new DerOctetString(kyberPublicKeyParameters.Rho)); - return new SubjectPublicKeyInfo(algorithmIdentifier, new DerSequence(v)); + + return new SubjectPublicKeyInfo(algorithmIdentifier, kyberPublicKeyParameters.GetEncoded()); } if (publicKey is DilithiumPublicKeyParameters dilithiumPublicKeyParameters) { |