summary refs log tree commit diff
path: root/crypto/src/pqc
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/src/pqc
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/src/pqc')
-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
3 files changed, 50 insertions, 22 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)
             {