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)
{
|