summary refs log tree commit diff
path: root/crypto
diff options
context:
space:
mode:
authorDavid Hook <david.hook@keyfactor.com>2022-11-08 11:39:43 +1100
committerDavid Hook <david.hook@keyfactor.com>2022-11-08 11:39:43 +1100
commit1be3f34021e60459b60f95088a173b11b87d9a2b (patch)
tree34d4abb9289b9e4b54eb9ddc1db51a400019be9b /crypto
parentfixed use of property (diff)
downloadBouncyCastle.NET-ed25519-1be3f34021e60459b60f95088a173b11b87d9a2b.tar.xz
fixed falcon signature format, added raw encoding for Falcon public key
Diffstat (limited to 'crypto')
-rw-r--r--crypto/src/pqc/crypto/falcon/FalconNIST.cs60
-rw-r--r--crypto/src/pqc/crypto/falcon/FalconSigner.cs4
-rw-r--r--crypto/src/pqc/crypto/utils/SubjectPublicKeyInfoFactory.cs8
-rw-r--r--crypto/test/src/pqc/crypto/test/FalconTest.cs76
4 files changed, 112 insertions, 36 deletions
diff --git a/crypto/src/pqc/crypto/falcon/FalconNIST.cs b/crypto/src/pqc/crypto/falcon/FalconNIST.cs
index 0d2ba46e0..0bc2adcad 100644
--- a/crypto/src/pqc/crypto/falcon/FalconNIST.cs
+++ b/crypto/src/pqc/crypto/falcon/FalconNIST.cs
@@ -124,7 +124,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Falcon
             return 0;
         }
 
-        internal byte[] crypto_sign(byte[] sm,
+        internal byte[] crypto_sign(bool attached, byte[] sm,
             byte[] msrc, int m, uint mlen,
             byte[] sksrc, int sk)
         {
@@ -214,19 +214,30 @@ namespace Org.BouncyCastle.Pqc.Crypto.Falcon
             */
             signer.sign_dyn(sig, 0, sc, f, 0, g, 0, F, 0, G, 0, hm, 0, this.logn, new FalconFPR[10 * n], 0);
 
-            /*
-             * Encode the signature. Format is:
-             *   signature header     1 bytes
-             *   nonce                40 bytes
-             *   signature            slen bytes
-             */
-            esig[0] = (byte)(0x20 + logn);
-            sig_len = codec.comp_encode(esig, 1, esig.Length - 1, sig, 0, logn);
-            if (sig_len == 0)
+            if (attached)
+            {
+                /*
+                 * Encode the signature. Format is:
+                 *   signature header     1 bytes
+                 *   nonce                40 bytes
+                 *   signature            slen bytes
+                 */
+                esig[0] = (byte)(0x20 + logn);
+                sig_len = codec.comp_encode(esig, 1, esig.Length - 1, sig, 0, logn);
+                if (sig_len == 0)
+                {
+                    throw new InvalidOperationException("signature failed to generate");
+                }
+                sig_len++;
+            }
+            else
             {
-                throw new InvalidOperationException("signature failed to generate");
+                sig_len = codec.comp_encode(esig, 0, esig.Length, sig, 0, logn);
+                if (sig_len == 0)
+                {
+                    throw new InvalidOperationException("signature failed to generate");
+                }
             }
-            sig_len++;
 
             // header
             sm[0] = (byte)(0x30 + logn);
@@ -239,7 +250,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Falcon
             return Arrays.CopyOfRange(sm, 0, 1 + (int)noncelen + sig_len);
         }
 
-        internal int crypto_sign_open(byte[] sig_encoded, byte[] nonce, byte[] m,
+        internal int crypto_sign_open(bool attached, byte[] sig_encoded, byte[] nonce, byte[] m,
             byte[] pksrc, int pk)
         {
             int sig_len, msg_len;
@@ -280,14 +291,27 @@ namespace Org.BouncyCastle.Pqc.Crypto.Falcon
             * Decode signature.
             */
             // esig = sm + 2 + this.noncelen + msg_len;
-            if (sig_len < 1 || sig_encoded[0] != (byte)(0x20 + this.logn)) {
-                return -1;
+            if (attached)
+            {
+                if (sig_len < 1 || sig_encoded[0] != (byte)(0x20 + this.logn))
+                {
+                    return -1;
+                }
+                if (this.codec.comp_decode(sig, 0, this.logn, sig_encoded,
+                    1, sig_len - 1) != sig_len - 1)
+                {
+                    return -1;
+                }
             }
-            if (this.codec.comp_decode(sig, 0, this.logn, sig_encoded,
-                1, sig_len - 1) != sig_len - 1)
+            else
             {
-                return -1;
+                if (sig_len < 1 || this.codec.comp_decode(sig, 0, this.logn, sig_encoded,
+    0, sig_len) != sig_len)
+                {
+                    return -1;
+                }
             }
+        
 
             /*
             * Hash nonce + message into a vector.
diff --git a/crypto/src/pqc/crypto/falcon/FalconSigner.cs b/crypto/src/pqc/crypto/falcon/FalconSigner.cs
index e77e84102..abfbe3c17 100644
--- a/crypto/src/pqc/crypto/falcon/FalconSigner.cs
+++ b/crypto/src/pqc/crypto/falcon/FalconSigner.cs
@@ -49,7 +49,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Falcon
         {
             byte[] sm = new byte[nist.GetCryptoBytes()];
 
-            return nist.crypto_sign(sm, message, 0, (uint)message.Length, encodedkey, 0);
+            return nist.crypto_sign(false, sm, message, 0, (uint)message.Length, encodedkey, 0);
         }
 
         public bool VerifySignature(byte[] message, byte[] signature)
@@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Falcon
             byte[] sig = new byte[signature.Length - nist.GetNonceLength() - 1];
             Array.Copy(signature, 1, nonce, 0, nist.GetNonceLength());
             Array.Copy(signature, nist.GetNonceLength() + 1, sig, 0, signature.Length - nist.GetNonceLength() - 1);
-            bool res = nist.crypto_sign_open(sig,nonce,message,encodedkey,0) == 0;
+            bool res = nist.crypto_sign_open(false, sig,nonce,message,encodedkey,0) == 0;
             return res;
         }
     }
diff --git a/crypto/src/pqc/crypto/utils/SubjectPublicKeyInfoFactory.cs b/crypto/src/pqc/crypto/utils/SubjectPublicKeyInfoFactory.cs
index b88834e50..f532cfdae 100644
--- a/crypto/src/pqc/crypto/utils/SubjectPublicKeyInfoFactory.cs
+++ b/crypto/src/pqc/crypto/utils/SubjectPublicKeyInfoFactory.cs
@@ -101,11 +101,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.Utilities
 #pragma warning restore CS0618 // Type or member is obsolete
             if (publicKey is FalconPublicKeyParameters falconPublicKeyParameters)
             {
-                byte[] encoding = falconPublicKeyParameters.GetEncoded();
+                byte[] keyEnc = falconPublicKeyParameters.GetEncoded();
+
+                byte[] encoding = new byte[keyEnc.Length + 1];
+                encoding[0] = (byte)(0x00 + falconPublicKeyParameters.Parameters.LogN);
+                Array.Copy(keyEnc, 0, encoding, 1, keyEnc.Length);
 
                 AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(
                     PqcUtilities.FalconOidLookup(falconPublicKeyParameters.Parameters));
-                return new SubjectPublicKeyInfo(algorithmIdentifier, new DerSequence(new DerOctetString(encoding)));
+                return new SubjectPublicKeyInfo(algorithmIdentifier, encoding);
             }
             if (publicKey is KyberPublicKeyParameters kyberPublicKeyParameters)
             {
diff --git a/crypto/test/src/pqc/crypto/test/FalconTest.cs b/crypto/test/src/pqc/crypto/test/FalconTest.cs
index c7421de6c..093f8e6a8 100644
--- a/crypto/test/src/pqc/crypto/test/FalconTest.cs
+++ b/crypto/test/src/pqc/crypto/test/FalconTest.cs
@@ -3,10 +3,11 @@ using System.Collections.Generic;
 using System.IO;
 
 using NUnit.Framework;
-
+using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.Parameters;
 using Org.BouncyCastle.Pqc.Crypto.Falcon;
+using Org.BouncyCastle.Pqc.Crypto.Utilities;
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Encoders;
 using Org.BouncyCastle.Utilities.Test;
@@ -31,6 +32,56 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests
             Assert.AreEqual(10, FalconParameters.falcon_1024.LogN);
         }
 
+        [Test]
+        public void TestKeyEncoding512()
+        {
+            byte[] altEncKey = Base64.Decode("vsUwFR+onoGQjgYmVpVBEacknmQpGTqsW+kNYw4VntPxVoRVLdsl2U24SzIAgrCZgwBAOnVK57arZT+5nF1afZZB5DzjapIKfPBhLlGmnQ6RX2j/WBaEoMAX7l46ZSb1GgycmZMgUFWvsYLEZr5D4zxOhfSkkzJ38NCzuOUNiFgYQ4TRtwxGwDM8WVV0vpL0nkLVnQJ7B0ZRBz++dXetoI651kjWW91GB3mj+x6U9SYx/KTF4zyejiEF2wVxKzgum13RiivF6cbBHLBeQLGBqRbgk5VasoRaswUc8NBywckHUBgmhilYUv0scpREs3m+IgjcYB2JmryzGNU1p6aM6b/sOrzJffLLm38mca6ZQpoNih03a+8QeIlAn8ns4XJOZOzg0J0ZsUhQ2Zdmj4BASFREAnma1LYH2k/rOf5qpfZUpYzuDhPJ43y5zLeUrt6kKErgGo4KYJBl4/JvWdlnFA8ROEbTY3qXEAHnkRzxsBOFX8midNdRVIDnRSJTZy1RNGFkcCOrpAad0HRVbCAvK6pT1gygOIltO6ap164lQu35kSJKP/a0xYFJgk25+WSK5DZThjVbA12Cb0WI5QRgfaM2+QZko8dDwsbbq05MMPLcy25HGHbqSGWIJLWFyGb0MisvSUnHGnKWL4x5JFP2VbSAtLzbdRCTg+mqcAkC5n1uxJcdZA6ReZ3biuV0RnLwEQhaPmpm2tbJl4w+UAni4mejObiRo8VGNUikK1L4Sig6DjMLON2nsvIEa8iDAaEJUbTLqy0iPWfl45v9HjY26FSpHVgl0GAfBAO0eagBOORzVX7iev0uqA2EGCrZCAdA5QvUTWK1RSA3O3hSXFm4+2A4jqainmxhfOtnuOCJxhZfbpkQ7BWHLLpl4B4LddyeXz2ug4KTzGeyugrDneZCqZ9TMp9URTyqBxmQmkYx3LsGQL4wMYMA6Q92iIQ+2jTBBQmkTNDlZKwjcOoi1eLSOwa3M/jhqiNA1HKsDWmKYoFg5qbPTYEJoDZqIDN6PJP4j++jQWlYW4MLhMXVFAlkWpQyHWcMRc9kpEvRd+hHSYl5G8Da3VSKsWgozoMb7aQbtwQxh0zhZgLJGBvYIyRkLaww0W5wLMJNg438+XOVAg0Olxk+4oVX6Xjpi1dIisTMumukfzOFCwIGgVsmWMVBit4woD7fVBNE5g38O2sdAfM=");
+            byte[] altSubPubEnc = Base64.Decode("MIIDljAHBgUrzg8DAQOCA4kAMIIDhASCA4C+xTAVH6iegZCOBiZWlUERpySeZCkZOqxb6Q1jDhWe0/FWhFUt2yXZTbhLMgCCsJmDAEA6dUrntqtlP7mcXVp9lkHkPONqkgp88GEuUaadDpFfaP9YFoSgwBfuXjplJvUaDJyZkyBQVa+xgsRmvkPjPE6F9KSTMnfw0LO45Q2IWBhDhNG3DEbAMzxZVXS+kvSeQtWdAnsHRlEHP751d62gjrnWSNZb3UYHeaP7HpT1JjH8pMXjPJ6OIQXbBXErOC6bXdGKK8XpxsEcsF5AsYGpFuCTlVqyhFqzBRzw0HLByQdQGCaGKVhS/SxylESzeb4iCNxgHYmavLMY1TWnpozpv+w6vMl98subfyZxrplCmg2KHTdr7xB4iUCfyezhck5k7ODQnRmxSFDZl2aPgEBIVEQCeZrUtgfaT+s5/mql9lSljO4OE8njfLnMt5Su3qQoSuAajgpgkGXj8m9Z2WcUDxE4RtNjepcQAeeRHPGwE4VfyaJ011FUgOdFIlNnLVE0YWRwI6ukBp3QdFVsIC8rqlPWDKA4iW07pqnXriVC7fmRIko/9rTFgUmCTbn5ZIrkNlOGNVsDXYJvRYjlBGB9ozb5BmSjx0PCxturTkww8tzLbkcYdupIZYgktYXIZvQyKy9JSccacpYvjHkkU/ZVtIC0vNt1EJOD6apwCQLmfW7Elx1kDpF5nduK5XRGcvARCFo+amba1smXjD5QCeLiZ6M5uJGjxUY1SKQrUvhKKDoOMws43aey8gRryIMBoQlRtMurLSI9Z+Xjm/0eNjboVKkdWCXQYB8EA7R5qAE45HNVfuJ6/S6oDYQYKtkIB0DlC9RNYrVFIDc7eFJcWbj7YDiOpqKebGF862e44InGFl9umRDsFYcsumXgHgt13J5fPa6DgpPMZ7K6CsOd5kKpn1Myn1RFPKoHGZCaRjHcuwZAvjAxgwDpD3aIhD7aNMEFCaRM0OVkrCNw6iLV4tI7Brcz+OGqI0DUcqwNaYpigWDmps9NgQmgNmogM3o8k/iP76NBaVhbgwuExdUUCWRalDIdZwxFz2SkS9F36EdJiXkbwNrdVIqxaCjOgxvtpBu3BDGHTOFmAskYG9gjJGQtrDDRbnAswk2Djfz5c5UCDQ6XGT7ihVfpeOmLV0iKxMy6a6R/M4ULAgaBWyZYxUGK3jCgPt9UE0TmDfw7ax0B8w==");
+
+            AsymmetricKeyParameter altPubDec = PublicKeyFactory.CreateKey(SubjectPublicKeyInfo.GetInstance(altSubPubEnc));
+            Assert.AreEqual(altEncKey, ((FalconPublicKeyParameters)altPubDec).GetEncoded());
+
+            Security.SecureRandom random = new Security.SecureRandom();
+            FalconKeyGenerationParameters kparam = new FalconKeyGenerationParameters(random, FalconParameters.falcon_512);
+            FalconKeyPairGenerator kpg = new FalconKeyPairGenerator();
+            kpg.Init(kparam);
+            AsymmetricCipherKeyPair ackp = kpg.GenerateKeyPair();
+
+            AsymmetricKeyParameter pub = ackp.Public;
+            AsymmetricKeyParameter priv = ackp.Private;
+
+            AsymmetricKeyParameter pubDec = PublicKeyFactory.CreateKey(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub));
+            AsymmetricKeyParameter privDec = PrivateKeyFactory.CreateKey(PrivateKeyInfoFactory.CreatePrivateKeyInfo(priv));
+
+            Assert.AreEqual(((FalconPublicKeyParameters)pub).GetEncoded(), ((FalconPublicKeyParameters)pubDec).GetEncoded());
+            Assert.AreEqual(((FalconPrivateKeyParameters)priv).GetEncoded(), ((FalconPrivateKeyParameters)privDec).GetEncoded());
+        }
+
+        [Test]
+        public void TestKeyEncoding1024()
+        {
+            byte[] altEncKey = Base64.Decode(" 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");
+            byte[] altSubPubEnc = Base64.Decode("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");
+
+            AsymmetricKeyParameter altPubDec = PublicKeyFactory.CreateKey(SubjectPublicKeyInfo.GetInstance(altSubPubEnc));
+            Assert.AreEqual(altEncKey, ((FalconPublicKeyParameters)altPubDec).GetEncoded());
+
+            Security.SecureRandom random = new Security.SecureRandom();
+            FalconKeyGenerationParameters kparam = new FalconKeyGenerationParameters(random, FalconParameters.falcon_1024);
+            FalconKeyPairGenerator kpg = new FalconKeyPairGenerator();
+            kpg.Init(kparam);
+            AsymmetricCipherKeyPair ackp = kpg.GenerateKeyPair();
+
+            AsymmetricKeyParameter pub = ackp.Public;
+            AsymmetricKeyParameter priv = ackp.Private;
+
+            AsymmetricKeyParameter pubDec = PublicKeyFactory.CreateKey(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub));
+            AsymmetricKeyParameter privDec = PrivateKeyFactory.CreateKey(PrivateKeyInfoFactory.CreatePrivateKeyInfo(priv));
+  
+            Assert.AreEqual(((FalconPublicKeyParameters)pub).GetEncoded(), ((FalconPublicKeyParameters)pubDec).GetEncoded());
+            Assert.AreEqual(((FalconPrivateKeyParameters)priv).GetEncoded(), ((FalconPrivateKeyParameters)privDec).GetEncoded());
+        }
+
         [TestCaseSource(nameof(TestVectorFiles))]
         [Parallelizable(ParallelScope.All)]
         public void TV(string testVectorFile)
@@ -69,25 +120,22 @@ namespace Org.BouncyCastle.Pqc.Crypto.Tests
             ParametersWithRandom skwrand = new ParametersWithRandom(ackp.Private, random);
             signer.Init(true, skwrand);
             byte[] sig = signer.GenerateSignature(msg);
-            byte[] ressm = new byte[2 + msg.Length + sig.Length - 1];
-            ressm[0] = (byte)((sig.Length - 40 - 1) >> 8);
-            ressm[1] = (byte)(sig.Length - 40 - 1);
+            byte[] ressm = new byte[2 + msg.Length + sig.Length];
+            ressm[0] = (byte)((sig.Length - 40) >> 8);
+            ressm[1] = (byte)(sig.Length - 40);
             Array.Copy(sig, 1, ressm, 2, 40);
             Array.Copy(msg, 0, ressm, 2 + 40, msg.Length);
-            Array.Copy(sig, 40 + 1, ressm, 2 + 40 + msg.Length, sig.Length - 40 - 1);
-
+            ressm[2 + 40 + msg.Length] = (byte)(0x20 + kparam.Parameters.LogN);
+            Array.Copy(sig, 40 + 1, ressm, 3 + 40 + msg.Length, sig.Length - 40 - 1);
+         
             // verify
             FalconSigner verifier = new FalconSigner();
             FalconPublicKeyParameters pkparam = (FalconPublicKeyParameters)ackp.Public;
             verifier.Init(false, pkparam);
-            byte[] noncesig = new byte[sm_len - m_len - 2 + 1];
-            noncesig[0] = (byte)(0x30 + falconParameters.LogN);
-            Array.Copy(sm, 2, noncesig, 1, 40);
-            Array.Copy(sm, 2 + 40 + m_len, noncesig, 40 + 1, sm_len - 2 - 40 - m_len);
-            bool vrfyrespass = verifier.VerifySignature(msg, noncesig);
-            noncesig[42]++; // changing the signature by 1 byte should cause it to fail
-            bool vrfyresfail = verifier.VerifySignature(msg, noncesig);
-                            
+            bool vrfyrespass = verifier.VerifySignature(msg, sig);
+            sig[42]++; // changing the signature by 1 byte should cause it to fail
+            bool vrfyresfail = verifier.VerifySignature(msg, sig);
+           
             //sign
             Assert.True(Arrays.AreEqual(ressm, sm), name + " " + count + " signature");
             //verify