Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions wrapper/CSharp/user_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@
#define ECC_TIMING_RESISTANT
#define HAVE_COMP_KEY

/* Enable ML-KEM, ML-DSA */
#define HAVE_MLKEM
#define WOLFSSL_WC_MLKEM
#define WOLFSSL_HAVE_MLKEM
#define WOLFSSL_DTLS_CH_FRAG
#define HAVE_DILITHIUM
#define WOLFSSL_WC_DILITHIUM
#define WOLFSSL_SHAKE128
#define WOLFSSL_SHAKE256

/* Disable features */
#define NO_PSK

Expand Down
305 changes: 305 additions & 0 deletions wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,299 @@ private static void curve25519_test()
if (publicKeyB != IntPtr.Zero) wolfcrypt.Curve25519FreeKey(publicKeyB);
} /* END curve25519_test */

private static void mlkem_test(wolfcrypt.MlKemTypes type)
{
int ret = 0;
IntPtr keyA = IntPtr.Zero;
IntPtr keyB = IntPtr.Zero;
IntPtr heap = IntPtr.Zero;
int devId = wolfcrypt.INVALID_DEVID;
byte[] pubA = null;
byte[] privA = null;
byte[] cipherText = null;
byte[] sharedSecretA = null;
byte[] sharedSecretB = null;

try
{
Console.WriteLine("\nStarting " + type + " shared secret test ...");

/* Generate Key Pair */
Console.WriteLine("Testing ML-KEM Key Generation...");

Console.WriteLine("Generate Key Pair A...");
keyA = wolfcrypt.MlKemMakeKey(type, heap, devId);
if (keyA == IntPtr.Zero)
{
ret = -1;
Console.Error.WriteLine("Failed to generate key pair A.");
}
if (ret == 0)
{
Console.WriteLine("Generate Key Pair B...");
keyB = wolfcrypt.MlKemMakeKey(type, heap, devId);
if (keyB == IntPtr.Zero)
{
ret = -1;
Console.Error.WriteLine("Failed to generate key pair B.");
}
}
if (ret == 0)
{
Console.WriteLine("ML-KEM Key Generation test passed.");
}

/* Encode */
if (ret == 0)
{
Console.WriteLine("Testing ML-KEM Key Encode...");
ret = wolfcrypt.MlKemEncodePublicKey(keyA, out pubA);
if (ret != 0)
{
Console.Error.WriteLine($"Failed to encode public key of A. Error code: {ret}");
}
}
if (ret == 0)
{
ret = wolfcrypt.MlKemEncodePrivateKey(keyA, out privA);
if (ret != 0)
{
Console.Error.WriteLine($"Failed to encode private key of A. Error code: {ret}");
}
}
if (ret == 0)
{
Console.WriteLine("ML-KEM Key Encode test passed.");
}

/* Encapsulate */
if (ret == 0)
{
Console.WriteLine("Testing ML-KEM Encapsulation...");
ret = wolfcrypt.MlKemEncapsulate(keyA, out cipherText, out sharedSecretA);
if (ret != 0)
{
Console.Error.WriteLine($"Failed to encapsulate. Error code: {ret}");
}
}
if (ret == 0)
{
Console.WriteLine("ML-KEM Encapsulation test passed.");
}

/* Decode */
if (ret == 0)
{
Console.WriteLine("Testing ML-KEM Decode...");
ret = wolfcrypt.MlKemDecodePrivateKey(keyB, privA);
if (ret != 0)
{
Console.Error.WriteLine($"Failed to decode private key of A. Error code: {ret}");
}
}
if (ret == 0)
{
ret = wolfcrypt.MlKemDecodePublicKey(keyB, pubA);
if (ret != 0)
{
Console.Error.WriteLine($"Failed to decode public key of B. Error code: {ret}");
}
}
if (ret == 0)
{
Console.WriteLine("ML-KEM Decode test passed.");
}

/* Decapsulate */
if (ret == 0)
{
Console.WriteLine("Testing ML-KEM Decapsulation...");
ret = wolfcrypt.MlKemDecapsulate(keyB, cipherText, out sharedSecretB);
if (ret != 0)
{
Console.Error.WriteLine($"Failed to decapsulate. Error code: {ret}");
}
}
if (ret == 0)
{
Console.WriteLine("ML-KEM Decapsulation test passed.");
}

/* Check */
if (ret == 0)
{
Console.WriteLine("Comparing Shared Secrets...");
if (!wolfcrypt.ByteArrayVerify(sharedSecretA, sharedSecretB))
{
ret = -1;
Console.Error.WriteLine($"Shared secrets do not match. Error code: {ret}");
}
}
if (ret == 0)
{
Console.WriteLine("ML-KEM shared secret match.");
}

if (ret != 0)
{
throw new Exception("ML-KEM test failed.");
}
}
catch (Exception ex)
{
Console.WriteLine($"ML-KEM test failed: {ex.Message}");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

./autogen.sh
cp wrapper/CSharp/user_settings.h .
./configure --enable-usersettings
make
cd wrapper/CSharp
mcs wolfCrypt-Test/wolfCrypt-Test.cs wolfSSL_CSharp/wolfCrypt.cs wolfSSL_CSharp/wolfSSL.cs wolfSSL_CSharp/X509.cs -OUT:wolfcrypttest.exe
mono wolfcrypttest.exe
Testing ML-KEM Key Generation...
Generate Key Pair A...
MlKem key creation exception: System.EntryPointNotFoundException: wc_MlKemKey_New assembly:<unknown assembly> type:<unknown type> member:(null)
  at (wrapper managed-to-native) wolfSSL.CSharp.wolfcrypt.wc_MlKemKey_New(int,intptr,int)
  at wolfSSL.CSharp.wolfcrypt.MlKemMakeKey (wolfSSL.CSharp.wolfcrypt+MlKemTypes type, System.IntPtr heap, System.Int32 devId) [0x00010] in <19b282451d9f4a87bc3d7c440f76d98a>:0 
Failed to generate key pair A.
ML-KEM test failed: ML-KEM test failed.
An error occurred: ML-KEM test failed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is strange. This API has already been added in #9039 .
Also, this doesn't happen when building with Visual Studio, etc.
There might be an issue with the DLL reference or build flag settings. I'll check it immediately.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1️⃣

cp wrapper/CSharp/user_settings.h .
./configure --enable-usersettings

I confirmed that ML-KEM/ML-DSA is not enabled in the above steps.
I will continue to investigate why this is happening.

2️⃣
And, in wolfSSL 5.9.0 (unchanged),

cp wrapper/CSharp/user_settings.h .
./configure --enable-usersettings
make
make check

I confirmed that this fails.
Specifically, the following two items fail:

  • testsuite/testsuite.test
  • scripts/unit.test

I would like to investigate these as well, but my knowledge in these areas is not extensive.
If you have any information, I would appreciate any advice you can offer.

throw;
}
finally
{
/* Cleanup */
if (keyA != IntPtr.Zero)
{
ret = wolfcrypt.MlKemFreeKey(ref keyA);
if (ret != 0)
{
Console.Error.WriteLine($"Failed to free MlKem key A. Error code: {ret}");
}
}
if (keyB != IntPtr.Zero)
{
ret = wolfcrypt.MlKemFreeKey(ref keyB);
if (ret != 0)
{
Console.Error.WriteLine($"Failed to free MlKem key B. Error code: {ret}");
}
}
}
} /* END mlkem_test */

private static void mldsa_test(wolfcrypt.MlDsaLevels level)
{
int ret = 0;
IntPtr key = IntPtr.Zero;
IntPtr heap = IntPtr.Zero;
int devId = wolfcrypt.INVALID_DEVID;
byte[] privateKey = null;
byte[] publicKey = null;
byte[] message = Encoding.UTF8.GetBytes("This is some data to sign with ML-DSA");
byte[] signature = null;

try
{
Console.WriteLine("\nStarting " + level + " key generation and signature test ...");

/* Generate Key */
Console.WriteLine("Testing ML-DSA Key Generation...");
key = wolfcrypt.DilithiumMakeKey(heap, devId, level);
if (key == IntPtr.Zero)
{
ret = -1;
Console.Error.WriteLine("Failed to generate keypair.");
}
if (ret == 0)
{
Console.WriteLine("ML-DSA Key Generation test passed.");
}

/* Export */
if (ret == 0)
{
Console.WriteLine("Testing ML-DSA Key Export...");
ret = DilithiumExportPrivateKey(key, out privateKey);
if (ret != 0)
{
Console.Error.WriteLine($"Failed to export private key. Error code: {ret}");
}
}
if (ret == 0)
{
ret = DilithiumExportPublicKey(key, out publicKey);
if (ret != 0)
{
Console.Error.WriteLine($"Failed to export public key. Error code: {ret}");
}
}
if (ret == 0)
{
Console.WriteLine("ML-DSA Key Export test passed.");
}

/* Import */
if (ret == 0)
{
Console.WriteLine("Testing ML-DSA Key Import...");
ret = DilithiumImportPrivateKey(privateKey, key);
if (ret != 0)
{
Console.Error.WriteLine($"Failed to import private key. Error code: {ret}");
}
}
if (ret == 0)
{
ret = DilithiumImportPublicKey(publicKey, key);
if (ret != 0)
{
Console.Error.WriteLine($"Failed to import public key. Error code: {ret}");
}
}
if (ret == 0)
{
Console.WriteLine("ML-DSA Key Import test passed.");
}

/* Sign */
if (ret == 0)
{
Console.WriteLine("Testing ML-DSA Signature Creation...");
ret = wolfcrypt.DilithiumSignMsg(key, message, out signature);
if (ret != 0)
{
Console.Error.WriteLine($"Failed to sign. Error code: {ret}");
}
}
if (ret == 0)
{
Console.WriteLine($"ML-DSA Signature Creation test passed. Signature Length: {signature.Length}");
}

/* Verify */
if (ret == 0)
{
Console.WriteLine("Testing ML-DSA Signature Verification...");
ret = wolfcrypt.DilithiumVerifyMsg(key, message, signature);
if (ret != 0)
{
Console.Error.WriteLine($"Failed to verify message. Error code: {ret}");
}
}
if (ret == 0)
{
Console.WriteLine("ML-DSA Signature Verification test passed.");
}

if (ret != 0)
{
throw new Exception("ML-DSA test failed.");
}
}
catch (Exception ex)
{
Console.WriteLine($"ML-DSA test failed: {ex.Message}");
throw;
}
finally
{
if (key != IntPtr.Zero)
{
ret = wolfcrypt.DilithiumFreeKey(ref key);
if (ret != 0)
{
Console.Error.WriteLine($"Failed to free ML-DSA key. Error code: {ret}");
}
}
}

} /* END mldsa_test */

private static void aes_gcm_test()
{
IntPtr aes = IntPtr.Zero;
Expand Down Expand Up @@ -930,6 +1223,18 @@ public static void Main(string[] args)

curve25519_test(); /* curve25519 shared secret test */

Console.WriteLine("\nStarting ML-KEM test");

mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_512); /* ML-KEM test */
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_768); /* ML-KEM test */
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_1024); /* ML-KEM test */

Console.WriteLine("\nStarting ML-DSA test");

mldsa_test(wolfcrypt.MlDsaLevels.ML_DSA_44); /* ML-DSA test */
mldsa_test(wolfcrypt.MlDsaLevels.ML_DSA_65); /* ML-DSA test */
mldsa_test(wolfcrypt.MlDsaLevels.ML_DSA_87); /* ML-DSA test */

Console.WriteLine("\nStarting AES-GCM test");

aes_gcm_test(); /* AES_GCM test */
Expand Down
Loading
Loading