Skip to content

Commit 6cfae96

Browse files
committed
add ML-KEM/ML-DSA support for C# wrapper
1 parent 7aab2f3 commit 6cfae96

File tree

4 files changed

+1268
-0
lines changed

4 files changed

+1268
-0
lines changed

wrapper/CSharp/user_settings.h

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

88+
/* Enable ML-KEM, ML-DSA */
89+
#define HAVE_MLKEM
90+
#define WOLFSSL_WC_MLKEM
91+
#define WOLFSSL_HAVE_MLKEM
92+
#define WOLFSSL_DTLS_CH_FRAG
93+
#define HAVE_DILITHIUM
94+
#define WOLFSSL_WC_DILITHIUM
95+
#define WOLFSSL_SHAKE128
96+
#define WOLFSSL_SHAKE256
97+
8898
/* Disable features */
8999
#define NO_PSK
90100

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

Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,289 @@ private static void curve25519_test()
648648
if (publicKeyB != IntPtr.Zero) wolfcrypt.Curve25519FreeKey(publicKeyB);
649649
} /* END curve25519_test */
650650

651+
private static void mlkem_test(wolfcrypt.MlKemTypes type)
652+
{
653+
int ret = 0;
654+
IntPtr keyA = IntPtr.Zero;
655+
IntPtr keyB = IntPtr.Zero;
656+
IntPtr heap = IntPtr.Zero;
657+
int devId = wolfcrypt.INVALID_DEVID;
658+
byte[] pubA, privA, cipherText, sharedSecretA, sharedSecretB;
659+
660+
try
661+
{
662+
Console.WriteLine("\nStarting " + type + " shared secret test ...");
663+
664+
/* Generate Key Pair */
665+
Console.WriteLine("Testing ML-KEM Key Generation...");
666+
667+
Console.WriteLine("Generate Key Pair A...");
668+
keyA = wolfcrypt.MlKemMakeKey(type, heap, devId);
669+
if (keyA == IntPtr.Zero)
670+
{
671+
ret = -1;
672+
Console.Error.WriteLine("Failed to generate key pair A.");
673+
}
674+
if (ret == 0)
675+
{
676+
Console.WriteLine("Generate Key Pair B...");
677+
keyB = wolfcrypt.MlKemMakeKey(type, heap, devId);
678+
if (keyB == IntPtr.Zero)
679+
{
680+
ret = -1;
681+
Console.Error.WriteLine("Failed to generate key pair B.");
682+
}
683+
}
684+
if (ret == 0)
685+
{
686+
Console.WriteLine("ML-KEM Key Generation test passed.");
687+
}
688+
689+
/* Encode */
690+
if (ret == 0)
691+
{
692+
Console.WriteLine("Testing ML-KEM Key Encode...");
693+
ret = wolfcrypt.MlKemEncodePublicKey(keyA, out pubA);
694+
if (ret != 0)
695+
{
696+
Console.Error.WriteLine("Failed to encode public key of A.");
697+
}
698+
}
699+
if (ret == 0)
700+
{
701+
ret = wolfcrypt.MlKemEncodePrivateKey(keyA, out privA);
702+
if (ret != 0)
703+
{
704+
Console.Error.WriteLine("Failed to encode private key of A.");
705+
}
706+
}
707+
if (ret == 0)
708+
{
709+
Console.WriteLine("ML-KEM Key Encode test passed.");
710+
}
711+
712+
/* Encapsulate */
713+
if (ret == 0)
714+
{
715+
Console.WriteLine("Testing ML-KEM Encapsulation...");
716+
ret = wolfcrypt.MlKemEncapsulate(keyA, out cipherText, out sharedSecretA);
717+
if (ret != 0)
718+
{
719+
Console.Error.WriteLine("Failed to encapsulate.");
720+
}
721+
}
722+
if (ret == 0)
723+
{
724+
Console.WriteLine("ML-KEM Encapsulation test passed.");
725+
}
726+
727+
/* Decode */
728+
if (ret == 0)
729+
{
730+
Console.WriteLine("Testing ML-KEM Decode...");
731+
ret = wolfcrypt.MlKemDecodePrivateKey(keyB, privA);
732+
if (ret != 0)
733+
{
734+
Console.Error.WriteLine("Failed to decode private key of A.");
735+
}
736+
}
737+
if (ret == 0)
738+
{
739+
ret = wolfcrypt.MlKemDecodePublicKey(keyB, pubA);
740+
if (ret != 0)
741+
{
742+
Console.Error.WriteLine("Failed to decode public key of B.");
743+
}
744+
}
745+
if (ret == 0)
746+
{
747+
Console.WriteLine("ML-KEM Decode test passed.");
748+
}
749+
750+
/* Decapsulate */
751+
if (ret == 0)
752+
{
753+
Console.WriteLine("Testing ML-KEM Decapsulation...");
754+
ret = wolfcrypt.MlKemDecapsulate(keyB, cipherText, out sharedSecretB);
755+
if (ret != 0)
756+
{
757+
Console.Error.WriteLine("Failed to decapsulate.");
758+
}
759+
}
760+
if (ret == 0)
761+
{
762+
Console.WriteLine("ML-KEM Decapsulation test passed.");
763+
}
764+
765+
/* DEBUG CODE FOR REVIEW */
766+
ret = BAD_FUNC_ARG;
767+
768+
/* Check */
769+
if (ret == 0)
770+
{
771+
Console.WriteLine("Comparing Shared Secrets...");
772+
if (!wolfcrypt.ByteArrayVerify(sharedSecretA, sharedSecretB))
773+
{
774+
Console.Error.WriteLine("Shared secrets do not match.");
775+
}
776+
else
777+
{
778+
Console.WriteLine("ML-KEM shared secret match.");
779+
}
780+
}
781+
}
782+
catch
783+
{
784+
// todo:
785+
// ........ https://github.com/wolfSSL/wolfssl/pull/9040#discussion_r2386193630
786+
// ........ https://github.com/wolfSSL/wolfssl/pull/9040#discussion_r2386194020
787+
}
788+
finally
789+
{
790+
/* Cleanup */
791+
if (keyA != IntPtr.Zero)
792+
{
793+
ret = wolfcrypt.MlKemFreeKey(keyA);
794+
if (ret != 0)
795+
{
796+
Console.Error.WriteLine("Failed to free MlKem key A. Error code: " + ret);
797+
}
798+
}
799+
if (keyB != IntPtr.Zero)
800+
{
801+
ret = wolfcrypt.MlKemFreeKey(keyB);
802+
if (ret != 0)
803+
{
804+
Console.Error.WriteLine("Failed to free MlKem key B. Error code: " + ret);
805+
}
806+
}
807+
}
808+
} /* END mlkem_test */
809+
810+
private static void mldsa_test(wolfcrypt.MlDsaTypes type)
811+
{
812+
int ret = 0;
813+
IntPtr key = IntPtr.Zero;
814+
IntPtr heap = IntPtr.Zero;
815+
int devId = wolfcrypt.INVALID_DEVID;
816+
byte[] privateKey;
817+
byte[] publicKey;
818+
byte[] message = Encoding.UTF8.GetBytes("This is some data to sign with ML-DSA");
819+
byte[] signature;
820+
821+
try
822+
{
823+
Console.WriteLine("\nStarting " + type + " shared secret test ...");
824+
825+
/* Generate Key */
826+
Console.WriteLine("Testing ML-DSA Key Generation...");
827+
key = wolfcrypt.DilithiumMakeKey(heap, devId, type);
828+
if (key == IntPtr.Zero)
829+
{
830+
ret = -1;
831+
Console.Error.WriteLine("DilithiumMakeKey failed");
832+
}
833+
if (ret == 0)
834+
{
835+
Console.WriteLine("ML-DSA Key Generation test passed.");
836+
}
837+
838+
/* Export */
839+
if (ret == 0)
840+
{
841+
Console.WriteLine("Testing ML-DSA Key Export...");
842+
ret = DilithiumExportPrivateKey(key, out privateKey);
843+
if (ret != 0)
844+
{
845+
Console.Error.WriteLine("DilithiumExportPrivateKey failed");
846+
}
847+
}
848+
if (ret == 0)
849+
{
850+
ret = DilithiumExportPublicKey(key, out publicKey);
851+
if (ret != 0)
852+
{
853+
Console.Error.WriteLine("DilithiumExportPublicKey failed");
854+
}
855+
}
856+
if (ret == 0)
857+
{
858+
Console.WriteLine("ML-DSA Key Export test passed.");
859+
}
860+
861+
/* Import */
862+
if (ret == 0)
863+
{
864+
Console.WriteLine("Testing ML-DSA Key Import...");
865+
ret = DilithiumImportPrivateKey(privateKey, key);
866+
if (ret != 0)
867+
{
868+
Console.Error.WriteLine("DilithiumImportPrivateKey failed");
869+
}
870+
}
871+
if (ret == 0)
872+
{
873+
ret = DilithiumImportPublicKey(publicKey, key);
874+
if (ret != 0)
875+
{
876+
Console.Error.WriteLine("DilithiumImportPrivateKey failed");
877+
}
878+
}
879+
if (ret == 0)
880+
{
881+
Console.WriteLine("ML-DSA Key Import test passed.");
882+
}
883+
884+
/* Sign */
885+
if (ret == 0)
886+
{
887+
Console.WriteLine("Testing ML-DSA Signature Creation...");
888+
ret = wolfcrypt.DilithiumSignMsg(key, message, out signature);
889+
if (ret != 0)
890+
{
891+
Console.Error.WriteLine("DilithiumSign failed");
892+
}
893+
}
894+
if (ret == 0)
895+
{
896+
Console.WriteLine($"ML-DSA Signature Creation test passed. Signature Length: {signature.Length}");
897+
}
898+
899+
/* Verify */
900+
if (ret == 0)
901+
{
902+
Console.WriteLine("Testing ML-DSA Signature Verification...");
903+
ret = wolfcrypt.DilithiumVerifyMsg(key, message, signature);
904+
if (ret != 0)
905+
{
906+
Console.Error.WriteLine("DilithiumVerify failed");
907+
}
908+
}
909+
if (ret == 0)
910+
{
911+
Console.WriteLine("ML-DSA Signature Verification test passed.");
912+
}
913+
}
914+
catch
915+
{
916+
// todo:
917+
// ........ https://github.com/wolfSSL/wolfssl/pull/9040#discussion_r2386193630
918+
// ........ https://github.com/wolfSSL/wolfssl/pull/9040#discussion_r2386194020
919+
}
920+
finally
921+
{
922+
if (key != IntPtr.Zero)
923+
{
924+
ret = wolfcrypt.DilithiumFreeKey(key);
925+
if (ret != 0)
926+
{
927+
Console.Error.WriteLine("Failed to free Dilithium key. Error code: " + ret);
928+
}
929+
}
930+
}
931+
932+
} /* END mldsa_test */
933+
651934
private static void aes_gcm_test()
652935
{
653936
IntPtr aes = IntPtr.Zero;
@@ -904,6 +1187,18 @@ public static void Main(string[] args)
9041187

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

1190+
Console.WriteLine("\nStarting ML-KEM test");
1191+
1192+
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_512); /* ML-KEM test */
1193+
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_768); /* ML-KEM test */
1194+
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_1024); /* ML-KEM test */
1195+
1196+
Console.WriteLine("\nStarting ML-DSA test");
1197+
1198+
mldsa_test(wolfcrypt.MlDsaTypes.ML_DSA_44); /* ML-DSA test */
1199+
mldsa_test(wolfcrypt.MlDsaTypes.ML_DSA_65); /* ML-DSA test */
1200+
mldsa_test(wolfcrypt.MlDsaTypes.ML_DSA_87); /* ML-DSA test */
1201+
9071202
Console.WriteLine("\nStarting AES-GCM test");
9081203

9091204
aes_gcm_test(); /* AES_GCM test */

0 commit comments

Comments
 (0)