Skip to content

Commit 21be377

Browse files
tamasan238dgarske
authored andcommitted
add ML-KEM/ML-DSA support for C# wrapper
1 parent 9176185 commit 21be377

4 files changed

Lines changed: 1364 additions & 0 deletions

File tree

wrapper/CSharp/user_settings.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,16 @@
8787
#define ECC_TIMING_RESISTANT
8888
#define HAVE_COMP_KEY
8989

90+
/* Enable ML-KEM, ML-DSA */
91+
#define HAVE_MLKEM
92+
#define WOLFSSL_WC_MLKEM
93+
#define WOLFSSL_HAVE_MLKEM
94+
#define WOLFSSL_DTLS_CH_FRAG
95+
#define HAVE_DILITHIUM
96+
#define WOLFSSL_WC_DILITHIUM
97+
#define WOLFSSL_SHAKE128
98+
#define WOLFSSL_SHAKE256
99+
90100
/* Disable features */
91101
#define NO_PSK
92102

wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs

Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,299 @@ private static void curve25519_test()
674674
if (publicKeyB != IntPtr.Zero) wolfcrypt.Curve25519FreeKey(publicKeyB);
675675
} /* END curve25519_test */
676676

677+
private static void mlkem_test(wolfcrypt.MlKemTypes type)
678+
{
679+
int ret = 0;
680+
IntPtr keyA = IntPtr.Zero;
681+
IntPtr keyB = IntPtr.Zero;
682+
IntPtr heap = IntPtr.Zero;
683+
int devId = wolfcrypt.INVALID_DEVID;
684+
byte[] pubA = null;
685+
byte[] privA = null;
686+
byte[] cipherText = null;
687+
byte[] sharedSecretA = null;
688+
byte[] sharedSecretB = null;
689+
690+
try
691+
{
692+
Console.WriteLine("\nStarting " + type + " shared secret test ...");
693+
694+
/* Generate Key Pair */
695+
Console.WriteLine("Testing ML-KEM Key Generation...");
696+
697+
Console.WriteLine("Generate Key Pair A...");
698+
keyA = wolfcrypt.MlKemMakeKey(type, heap, devId);
699+
if (keyA == IntPtr.Zero)
700+
{
701+
ret = -1;
702+
Console.Error.WriteLine("Failed to generate key pair A.");
703+
}
704+
if (ret == 0)
705+
{
706+
Console.WriteLine("Generate Key Pair B...");
707+
keyB = wolfcrypt.MlKemMakeKey(type, heap, devId);
708+
if (keyB == IntPtr.Zero)
709+
{
710+
ret = -1;
711+
Console.Error.WriteLine("Failed to generate key pair B.");
712+
}
713+
}
714+
if (ret == 0)
715+
{
716+
Console.WriteLine("ML-KEM Key Generation test passed.");
717+
}
718+
719+
/* Encode */
720+
if (ret == 0)
721+
{
722+
Console.WriteLine("Testing ML-KEM Key Encode...");
723+
ret = wolfcrypt.MlKemEncodePublicKey(keyA, out pubA);
724+
if (ret != 0)
725+
{
726+
Console.Error.WriteLine($"Failed to encode public key of A. Error code: {ret}");
727+
}
728+
}
729+
if (ret == 0)
730+
{
731+
ret = wolfcrypt.MlKemEncodePrivateKey(keyA, out privA);
732+
if (ret != 0)
733+
{
734+
Console.Error.WriteLine($"Failed to encode private key of A. Error code: {ret}");
735+
}
736+
}
737+
if (ret == 0)
738+
{
739+
Console.WriteLine("ML-KEM Key Encode test passed.");
740+
}
741+
742+
/* Encapsulate */
743+
if (ret == 0)
744+
{
745+
Console.WriteLine("Testing ML-KEM Encapsulation...");
746+
ret = wolfcrypt.MlKemEncapsulate(keyA, out cipherText, out sharedSecretA);
747+
if (ret != 0)
748+
{
749+
Console.Error.WriteLine($"Failed to encapsulate. Error code: {ret}");
750+
}
751+
}
752+
if (ret == 0)
753+
{
754+
Console.WriteLine("ML-KEM Encapsulation test passed.");
755+
}
756+
757+
/* Decode */
758+
if (ret == 0)
759+
{
760+
Console.WriteLine("Testing ML-KEM Decode...");
761+
ret = wolfcrypt.MlKemDecodePrivateKey(keyB, privA);
762+
if (ret != 0)
763+
{
764+
Console.Error.WriteLine($"Failed to decode private key of A. Error code: {ret}");
765+
}
766+
}
767+
if (ret == 0)
768+
{
769+
ret = wolfcrypt.MlKemDecodePublicKey(keyB, pubA);
770+
if (ret != 0)
771+
{
772+
Console.Error.WriteLine($"Failed to decode public key of B. Error code: {ret}");
773+
}
774+
}
775+
if (ret == 0)
776+
{
777+
Console.WriteLine("ML-KEM Decode test passed.");
778+
}
779+
780+
/* Decapsulate */
781+
if (ret == 0)
782+
{
783+
Console.WriteLine("Testing ML-KEM Decapsulation...");
784+
ret = wolfcrypt.MlKemDecapsulate(keyB, cipherText, out sharedSecretB);
785+
if (ret != 0)
786+
{
787+
Console.Error.WriteLine($"Failed to decapsulate. Error code: {ret}");
788+
}
789+
}
790+
if (ret == 0)
791+
{
792+
Console.WriteLine("ML-KEM Decapsulation test passed.");
793+
}
794+
795+
/* Check */
796+
if (ret == 0)
797+
{
798+
Console.WriteLine("Comparing Shared Secrets...");
799+
if (!wolfcrypt.ByteArrayVerify(sharedSecretA, sharedSecretB))
800+
{
801+
ret = -1;
802+
Console.Error.WriteLine($"Shared secrets do not match. Error code: {ret}");
803+
}
804+
}
805+
if (ret == 0)
806+
{
807+
Console.WriteLine("ML-KEM shared secret match.");
808+
}
809+
810+
if (ret != 0)
811+
{
812+
throw new Exception("ML-KEM test failed.");
813+
}
814+
}
815+
catch (Exception ex)
816+
{
817+
Console.WriteLine($"ML-KEM test failed: {ex.Message}");
818+
throw;
819+
}
820+
finally
821+
{
822+
/* Cleanup */
823+
if (keyA != IntPtr.Zero)
824+
{
825+
ret = wolfcrypt.MlKemFreeKey(ref keyA);
826+
if (ret != 0)
827+
{
828+
Console.Error.WriteLine($"Failed to free MlKem key A. Error code: {ret}");
829+
}
830+
}
831+
if (keyB != IntPtr.Zero)
832+
{
833+
ret = wolfcrypt.MlKemFreeKey(ref keyB);
834+
if (ret != 0)
835+
{
836+
Console.Error.WriteLine($"Failed to free MlKem key B. Error code: {ret}");
837+
}
838+
}
839+
}
840+
} /* END mlkem_test */
841+
842+
private static void mldsa_test(wolfcrypt.MlDsaLevels level)
843+
{
844+
int ret = 0;
845+
IntPtr key = IntPtr.Zero;
846+
IntPtr heap = IntPtr.Zero;
847+
int devId = wolfcrypt.INVALID_DEVID;
848+
byte[] privateKey = null;
849+
byte[] publicKey = null;
850+
byte[] message = Encoding.UTF8.GetBytes("This is some data to sign with ML-DSA");
851+
byte[] signature = null;
852+
853+
try
854+
{
855+
Console.WriteLine("\nStarting " + level + " key generation and signature test ...");
856+
857+
/* Generate Key */
858+
Console.WriteLine("Testing ML-DSA Key Generation...");
859+
key = wolfcrypt.DilithiumMakeKey(heap, devId, level);
860+
if (key == IntPtr.Zero)
861+
{
862+
ret = -1;
863+
Console.Error.WriteLine("Failed to generate keypair.");
864+
}
865+
if (ret == 0)
866+
{
867+
Console.WriteLine("ML-DSA Key Generation test passed.");
868+
}
869+
870+
/* Export */
871+
if (ret == 0)
872+
{
873+
Console.WriteLine("Testing ML-DSA Key Export...");
874+
ret = DilithiumExportPrivateKey(key, out privateKey);
875+
if (ret != 0)
876+
{
877+
Console.Error.WriteLine($"Failed to export private key. Error code: {ret}");
878+
}
879+
}
880+
if (ret == 0)
881+
{
882+
ret = DilithiumExportPublicKey(key, out publicKey);
883+
if (ret != 0)
884+
{
885+
Console.Error.WriteLine($"Failed to export public key. Error code: {ret}");
886+
}
887+
}
888+
if (ret == 0)
889+
{
890+
Console.WriteLine("ML-DSA Key Export test passed.");
891+
}
892+
893+
/* Import */
894+
if (ret == 0)
895+
{
896+
Console.WriteLine("Testing ML-DSA Key Import...");
897+
ret = DilithiumImportPrivateKey(privateKey, key);
898+
if (ret != 0)
899+
{
900+
Console.Error.WriteLine($"Failed to import private key. Error code: {ret}");
901+
}
902+
}
903+
if (ret == 0)
904+
{
905+
ret = DilithiumImportPublicKey(publicKey, key);
906+
if (ret != 0)
907+
{
908+
Console.Error.WriteLine($"Failed to import public key. Error code: {ret}");
909+
}
910+
}
911+
if (ret == 0)
912+
{
913+
Console.WriteLine("ML-DSA Key Import test passed.");
914+
}
915+
916+
/* Sign */
917+
if (ret == 0)
918+
{
919+
Console.WriteLine("Testing ML-DSA Signature Creation...");
920+
ret = wolfcrypt.DilithiumSignMsg(key, message, out signature);
921+
if (ret != 0)
922+
{
923+
Console.Error.WriteLine($"Failed to sign. Error code: {ret}");
924+
}
925+
}
926+
if (ret == 0)
927+
{
928+
Console.WriteLine($"ML-DSA Signature Creation test passed. Signature Length: {signature.Length}");
929+
}
930+
931+
/* Verify */
932+
if (ret == 0)
933+
{
934+
Console.WriteLine("Testing ML-DSA Signature Verification...");
935+
ret = wolfcrypt.DilithiumVerifyMsg(key, message, signature);
936+
if (ret != 0)
937+
{
938+
Console.Error.WriteLine($"Failed to verify message. Error code: {ret}");
939+
}
940+
}
941+
if (ret == 0)
942+
{
943+
Console.WriteLine("ML-DSA Signature Verification test passed.");
944+
}
945+
946+
if (ret != 0)
947+
{
948+
throw new Exception("ML-DSA test failed.");
949+
}
950+
}
951+
catch (Exception ex)
952+
{
953+
Console.WriteLine($"ML-DSA test failed: {ex.Message}");
954+
throw;
955+
}
956+
finally
957+
{
958+
if (key != IntPtr.Zero)
959+
{
960+
ret = wolfcrypt.DilithiumFreeKey(ref key);
961+
if (ret != 0)
962+
{
963+
Console.Error.WriteLine($"Failed to free ML-DSA key. Error code: {ret}");
964+
}
965+
}
966+
}
967+
968+
} /* END mldsa_test */
969+
677970
private static void aes_gcm_test()
678971
{
679972
IntPtr aes = IntPtr.Zero;
@@ -1126,6 +1419,18 @@ public static void Main(string[] args)
11261419

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

1422+
Console.WriteLine("\nStarting ML-KEM test");
1423+
1424+
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_512); /* ML-KEM test */
1425+
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_768); /* ML-KEM test */
1426+
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_1024); /* ML-KEM test */
1427+
1428+
Console.WriteLine("\nStarting ML-DSA test");
1429+
1430+
mldsa_test(wolfcrypt.MlDsaLevels.ML_DSA_44); /* ML-DSA test */
1431+
mldsa_test(wolfcrypt.MlDsaLevels.ML_DSA_65); /* ML-DSA test */
1432+
mldsa_test(wolfcrypt.MlDsaLevels.ML_DSA_87); /* ML-DSA test */
1433+
11291434
Console.WriteLine("\nStarting AES-GCM test");
11301435

11311436
aes_gcm_test(); /* AES_GCM test */

0 commit comments

Comments
 (0)