summary refs log tree commit diff
path: root/crypto/src/pqc/asn1
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2023-05-02 20:55:51 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2023-05-02 20:55:51 +0700
commit4332f34f7a60dc07bdbf5ef894b3d529568a859a (patch)
treeda626963aa3b99b42621706d7f9676d78de12b0a /crypto/src/pqc/asn1
parentUpdate XMSS OIDs (diff)
downloadBouncyCastle.NET-ed25519-4332f34f7a60dc07bdbf5ef894b3d529568a859a.tar.xz
Update SphincsPlus from bc-java
- refactoring in Pqc
Diffstat (limited to 'crypto/src/pqc/asn1')
-rw-r--r--crypto/src/pqc/asn1/CmcePrivateKey.cs5
-rw-r--r--crypto/src/pqc/asn1/CmcePublicKey.cs8
-rw-r--r--crypto/src/pqc/asn1/PqcObjectIdentifiers.cs103
-rw-r--r--crypto/src/pqc/asn1/SphincsPlusPrivateKey.cs96
-rw-r--r--crypto/src/pqc/asn1/SphincsPlusPublicKey.cs61
5 files changed, 273 insertions, 0 deletions
diff --git a/crypto/src/pqc/asn1/CmcePrivateKey.cs b/crypto/src/pqc/asn1/CmcePrivateKey.cs
index 44b52ca56..26df9b7a8 100644
--- a/crypto/src/pqc/asn1/CmcePrivateKey.cs
+++ b/crypto/src/pqc/asn1/CmcePrivateKey.cs
@@ -32,6 +32,11 @@ namespace Org.BouncyCastle.Pqc.Asn1
             return new CmcePrivateKey(Asn1Sequence.GetInstance(o));
         }
 
+        public static CmcePrivateKey GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return GetInstance(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
         private int version;
         private byte[] delta;
         private byte[] c;
diff --git a/crypto/src/pqc/asn1/CmcePublicKey.cs b/crypto/src/pqc/asn1/CmcePublicKey.cs
index 26bd6e438..c9feebdf5 100644
--- a/crypto/src/pqc/asn1/CmcePublicKey.cs
+++ b/crypto/src/pqc/asn1/CmcePublicKey.cs
@@ -15,7 +15,14 @@ namespace Org.BouncyCastle.Pqc.Asn1
                 return null;
             if (o is CmcePublicKey cmcePublicKey)
                 return cmcePublicKey;
+#pragma warning disable CS0618 // Type or member is obsolete
             return new CmcePublicKey(Asn1Sequence.GetInstance(o));
+#pragma warning restore CS0618 // Type or member is obsolete
+        }
+
+        public static CmcePublicKey GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return GetInstance(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
         }
 
         private byte[] t;
@@ -25,6 +32,7 @@ namespace Org.BouncyCastle.Pqc.Asn1
             this.t = t;
         }
 
+        [Obsolete("Use 'GetInstance' instead")]
         public CmcePublicKey(Asn1Sequence seq)
         {
             t = Arrays.Clone(Asn1OctetString.GetInstance(seq[0]).GetOctets());
diff --git a/crypto/src/pqc/asn1/PqcObjectIdentifiers.cs b/crypto/src/pqc/asn1/PqcObjectIdentifiers.cs
new file mode 100644
index 000000000..94516f6f2
--- /dev/null
+++ b/crypto/src/pqc/asn1/PqcObjectIdentifiers.cs
@@ -0,0 +1,103 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.BC;
+
+namespace Org.BouncyCastle.Pqc.Asn1
+{
+    public static class PqcObjectIdentifiers
+    {
+        /** 1.3.6.1.4.1.8301.3.1.3.5.3.2 */
+        public static readonly DerObjectIdentifier rainbow = new DerObjectIdentifier("1.3.6.1.4.1.8301.3.1.3.5.3.2");
+
+        /** 1.3.6.1.4.1.8301.3.1.3.5.3.2.1 */
+        public static readonly DerObjectIdentifier rainbowWithSha1   = rainbow.Branch("1");
+        /** 1.3.6.1.4.1.8301.3.1.3.5.3.2.2 */
+        public static readonly DerObjectIdentifier rainbowWithSha224 = rainbow.Branch("2");
+        /** 1.3.6.1.4.1.8301.3.1.3.5.3.2.3 */
+        public static readonly DerObjectIdentifier rainbowWithSha256 = rainbow.Branch("3");
+        /** 1.3.6.1.4.1.8301.3.1.3.5.3.2.4 */
+        public static readonly DerObjectIdentifier rainbowWithSha384 = rainbow.Branch("4");
+        /** 1.3.6.1.4.1.8301.3.1.3.5.3.2.5 */
+        public static readonly DerObjectIdentifier rainbowWithSha512 = rainbow.Branch("5");
+
+        /** 1.3.6.1.4.1.8301.3.1.3.3 */
+        public static readonly DerObjectIdentifier gmss = new DerObjectIdentifier("1.3.6.1.4.1.8301.3.1.3.3");
+
+        /** 1.3.6.1.4.1.8301.3.1.3.3.1 */
+        public static readonly DerObjectIdentifier gmssWithSha1   = gmss.Branch("1");
+        /** 1.3.6.1.4.1.8301.3.1.3.3.2 */
+        public static readonly DerObjectIdentifier gmssWithSha224 = gmss.Branch("2");
+        /** 1.3.6.1.4.1.8301.3.1.3.3.3 */
+        public static readonly DerObjectIdentifier gmssWithSha256 = gmss.Branch("3");
+        /** 1.3.6.1.4.1.8301.3.1.3.3.4 */
+        public static readonly DerObjectIdentifier gmssWithSha384 = gmss.Branch("4");
+        /** 1.3.6.1.4.1.8301.3.1.3.3.5 */
+        public static readonly DerObjectIdentifier gmssWithSha512 = gmss.Branch("5");
+
+        /** 1.3.6.1.4.1.8301.3.1.3.4.1 */
+        public static readonly DerObjectIdentifier mcEliece       = new DerObjectIdentifier("1.3.6.1.4.1.8301.3.1.3.4.1");
+
+        /** 1.3.6.1.4.1.8301.3.1.3.4.2 */
+        public static readonly DerObjectIdentifier mcElieceCca2   = new DerObjectIdentifier("1.3.6.1.4.1.8301.3.1.3.4.2");
+
+        public static readonly DerObjectIdentifier mcElieceFujisaki    = new DerObjectIdentifier("1.3.6.1.4.1.8301.3.1.3.4.2.1");
+        public static readonly DerObjectIdentifier mcEliecePointcheval = new DerObjectIdentifier("1.3.6.1.4.1.8301.3.1.3.4.2.2");
+        public static readonly DerObjectIdentifier mcElieceKobara_Imai = new DerObjectIdentifier("1.3.6.1.4.1.8301.3.1.3.4.2.3");
+
+        public static readonly DerObjectIdentifier sphincs256 = BCObjectIdentifiers.sphincs256;
+        public static readonly DerObjectIdentifier sphincs256_with_BLAKE512 = BCObjectIdentifiers.sphincs256_with_BLAKE512;
+        public static readonly DerObjectIdentifier sphincs256_with_SHA512 = BCObjectIdentifiers.sphincs256_with_SHA512;
+        public static readonly DerObjectIdentifier sphincs256_with_SHA3_512 = BCObjectIdentifiers.sphincs256_with_SHA3_512;
+
+        public static readonly DerObjectIdentifier newHope = BCObjectIdentifiers.newHope;
+
+        /**
+         * XMSS
+         */
+        public static readonly DerObjectIdentifier xmss                      = BCObjectIdentifiers.xmss;
+        public static readonly DerObjectIdentifier xmss_SHA256ph             = BCObjectIdentifiers.xmss_SHA256ph;
+        public static readonly DerObjectIdentifier xmss_SHA512ph             = BCObjectIdentifiers.xmss_SHA512ph;
+        public static readonly DerObjectIdentifier xmss_SHAKE128ph           = BCObjectIdentifiers.xmss_SHAKE128ph;
+        public static readonly DerObjectIdentifier xmss_SHAKE256ph           = BCObjectIdentifiers.xmss_SHAKE256ph;
+        public static readonly DerObjectIdentifier xmss_SHA256               = BCObjectIdentifiers.xmss_SHA256;
+        public static readonly DerObjectIdentifier xmss_SHA512               = BCObjectIdentifiers.xmss_SHA512;
+        public static readonly DerObjectIdentifier xmss_SHAKE128             = BCObjectIdentifiers.xmss_SHAKE128;
+        public static readonly DerObjectIdentifier xmss_SHAKE256             = BCObjectIdentifiers.xmss_SHAKE256;
+
+
+        /**
+         * XMSS^MT
+         */
+        public static readonly DerObjectIdentifier xmss_mt                   = BCObjectIdentifiers.xmss_mt;
+        public static readonly DerObjectIdentifier xmss_mt_SHA256ph          = BCObjectIdentifiers.xmss_mt_SHA256ph;
+        public static readonly DerObjectIdentifier xmss_mt_SHA512ph          = BCObjectIdentifiers.xmss_mt_SHA512ph;
+        public static readonly DerObjectIdentifier xmss_mt_SHAKE128ph        = BCObjectIdentifiers.xmss_mt_SHAKE128ph;
+        public static readonly DerObjectIdentifier xmss_mt_SHAKE256ph        = BCObjectIdentifiers.xmss_mt_SHAKE256ph;
+        public static readonly DerObjectIdentifier xmss_mt_SHA256            = BCObjectIdentifiers.xmss_mt_SHA256;
+        public static readonly DerObjectIdentifier xmss_mt_SHA512            = BCObjectIdentifiers.xmss_mt_SHA512;
+        public static readonly DerObjectIdentifier xmss_mt_SHAKE128          = BCObjectIdentifiers.xmss_mt_SHAKE128;
+        public static readonly DerObjectIdentifier xmss_mt_SHAKE256          = BCObjectIdentifiers.xmss_mt_SHAKE256;
+
+        /**
+         * qTESLA
+         */
+        public static readonly DerObjectIdentifier qTESLA = BCObjectIdentifiers.qTESLA;
+        public static readonly DerObjectIdentifier qTESLA_p_I = BCObjectIdentifiers.qTESLA_p_I;
+        public static readonly DerObjectIdentifier qTESLA_p_III = BCObjectIdentifiers.qTESLA_p_III;
+
+        /**
+         * Explicit composite algorithms
+         */
+        public static readonly DerObjectIdentifier id_Dilithium3_RSA_PKCS15_SHA256 = new DerObjectIdentifier("2.16.840.1.114027.80.5.1.1");
+        public static readonly DerObjectIdentifier id_Dilithium3_ECDSA_P256_SHA256 = new DerObjectIdentifier("2.16.840.1.114027.80.5.1.2");
+        public static readonly DerObjectIdentifier id_Dilithium3_ECDSA_brainpoolP256r1_SHA256 = new DerObjectIdentifier("2.16.840.1.114027.80.5.1.3");
+        public static readonly DerObjectIdentifier id_Dilithium3_Ed25519 = new DerObjectIdentifier("2.16.840.1.114027.80.5.1.4");
+        public static readonly DerObjectIdentifier id_Dilithium5_ECDSA_P384_SHA384 = new DerObjectIdentifier("2.16.840.1.114027.80.5.1.5");
+        public static readonly DerObjectIdentifier id_Dilithium5_ECDSA_brainpoolP384r1_SHA384 = new DerObjectIdentifier("2.16.840.1.114027.80.5.1.6");
+        public static readonly DerObjectIdentifier id_Dilithium5_Ed448 = new DerObjectIdentifier("2.16.840.1.114027.80.5.1.7");
+        public static readonly DerObjectIdentifier id_Falcon512_ECDSA_P256_SHA256 = new DerObjectIdentifier("2.16.840.1.114027.80.5.1.8");
+        public static readonly DerObjectIdentifier id_Falcon512_ECDSA_brainpoolP256r1_SHA256 = new DerObjectIdentifier("2.16.840.1.114027.80.5.1.9");
+        public static readonly DerObjectIdentifier id_Falcon512_Ed25519 = new DerObjectIdentifier("2.16.840.1.114027.80.5.1.10");
+    }
+}
diff --git a/crypto/src/pqc/asn1/SphincsPlusPrivateKey.cs b/crypto/src/pqc/asn1/SphincsPlusPrivateKey.cs
new file mode 100644
index 000000000..67bef31ad
--- /dev/null
+++ b/crypto/src/pqc/asn1/SphincsPlusPrivateKey.cs
@@ -0,0 +1,96 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Pqc.Asn1
+{
+    /**
+     * See https://datatracker.ietf.org/doc/draft-uni-qsckeys-sphincsplus/00/ for details
+     * ASN.1 Encoding for a
+     * SphincsPlus private key for fully populated:
+     * <pre>
+     *   SPHINCSPLUSPrivateKey ::= SEQUENCE {
+     *     version          INTEGER {v2(1)}     --syntax version 2 (round 3)
+     *     skseed          OCTET STRING,        --n-byte private key seed
+     *     skprf           OCTET STRING,        --n-byte private key seed
+     *     PublicKey       SPHINCSPLUSPublicKey --public key
+     *   }
+     * </pre>
+     */
+    public sealed class SphincsPlusPrivateKey
+        : Asn1Encodable
+    {
+        public static SphincsPlusPrivateKey GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is SphincsPlusPrivateKey sphincsPlusPrivateKey)
+                return sphincsPlusPrivateKey;
+            return new SphincsPlusPrivateKey(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static SphincsPlusPrivateKey GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return GetInstance(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
+        public SphincsPlusPrivateKey(int version, byte[] skseed, byte[] skprf)
+            : this(version, skseed, skprf, null)
+        {
+        }
+
+        public SphincsPlusPrivateKey(int version, byte[] skseed, byte[] skprf, SphincsPlusPublicKey publicKey)
+        {
+            m_version = version;
+            m_skseed = skseed;
+            m_skprf = skprf;
+            m_publicKey = publicKey;
+        }
+
+        private SphincsPlusPrivateKey(Asn1Sequence seq)
+        {
+            m_version = DerInteger.GetInstance(seq[0]).IntValueExact;
+            if (m_version != 0)
+                throw new ArgumentException("unrecognized version");
+
+            m_skseed = Arrays.Clone(Asn1OctetString.GetInstance(seq[1]).GetOctets());
+
+            m_skprf = Arrays.Clone(Asn1OctetString.GetInstance(seq[2]).GetOctets());
+
+            if (seq.Count == 4)
+            {
+                m_publicKey = SphincsPlusPublicKey.GetInstance(seq[3]);
+            }
+        }
+
+        private readonly int m_version;
+        private readonly byte[] m_skseed;
+        private readonly byte[] m_skprf;
+        private readonly SphincsPlusPublicKey m_publicKey;
+
+        public byte[] GetSkprf() => Arrays.Clone(m_skprf);
+
+        public byte[] GetSkseed() => Arrays.Clone(m_skseed);
+
+        public SphincsPlusPublicKey PublicKey => m_publicKey;
+
+        public int Version => m_version;
+
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(4);
+
+            v.Add(new DerInteger(m_version));
+            v.Add(new DerOctetString(m_skseed));
+            v.Add(new DerOctetString(m_skprf));
+
+            if (m_publicKey != null)
+            {
+                v.Add(new SphincsPlusPublicKey(m_publicKey.GetPkseed(), m_publicKey.GetPkroot()));
+            }
+
+            return new DerSequence(v);
+        }
+    }
+}
diff --git a/crypto/src/pqc/asn1/SphincsPlusPublicKey.cs b/crypto/src/pqc/asn1/SphincsPlusPublicKey.cs
new file mode 100644
index 000000000..41e2158a7
--- /dev/null
+++ b/crypto/src/pqc/asn1/SphincsPlusPublicKey.cs
@@ -0,0 +1,61 @@
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Pqc.Asn1
+{
+    /**
+     * See https://datatracker.ietf.org/doc/draft-uni-qsckeys-sphincsplus/00/ for details.
+     * ASN.1 Encoding for a
+     * SphincsPlus public key for fully populated:
+     * <pre>
+     *   SPHINCSPPLUSPublicKey := SEQUENCE {
+     *     pkseed          OCTET STRING,     --n-byte public key seed
+     *     pkroot          OCTET STRING      --n-byte public hypertree root
+     *   }
+     * </pre>
+     */
+    public sealed class SphincsPlusPublicKey
+        : Asn1Encodable
+    {
+        public static SphincsPlusPublicKey GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is SphincsPlusPublicKey sphincsPlusPublicKey)
+                return sphincsPlusPublicKey;
+            return new SphincsPlusPublicKey(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static SphincsPlusPublicKey GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return GetInstance(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
+        private readonly byte[] m_pkseed;
+        private readonly byte[] m_pkroot;
+
+        public SphincsPlusPublicKey(byte[] pkseed, byte[] pkroot)
+        {
+            m_pkseed = pkseed;
+            m_pkroot = pkroot;
+        }
+
+        private SphincsPlusPublicKey(Asn1Sequence seq)
+        {
+            m_pkseed = Arrays.Clone(Asn1OctetString.GetInstance(seq[0]).GetOctets());
+            m_pkroot = Arrays.Clone(Asn1OctetString.GetInstance(seq[1]).GetOctets());
+        }
+
+        public byte[] GetPkroot() => Arrays.Clone(m_pkroot);
+
+        public byte[] GetPkseed() => Arrays.Clone(m_pkseed);
+
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector();
+            v.Add(new DerOctetString(m_pkseed));
+            v.Add(new DerOctetString(m_pkroot));
+            return new DerSequence(v);
+        }
+    }
+}