Skip to content

Commit 02ce87d

Browse files
committed
add ML-KEM/ML-DSA support for C# wrapper
1 parent b5c5327 commit 02ce87d

4 files changed

Lines changed: 1328 additions & 0 deletions

File tree

wrapper/CSharp/user_settings.h

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

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

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

Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,296 @@ 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+
Console.Error.WriteLine("Shared secrets do not match.");
802+
}
803+
else
804+
{
805+
Console.WriteLine("ML-KEM shared secret match.");
806+
}
807+
}
808+
809+
if (ret != 0)
810+
{
811+
throw new Exception("ML-KEM test failed.");
812+
}
813+
}
814+
catch (Exception ex)
815+
{
816+
Console.WriteLine($"ML-KEM test failed: {ex.Message}");
817+
}
818+
finally
819+
{
820+
/* Cleanup */
821+
if (keyA != IntPtr.Zero)
822+
{
823+
ret = wolfcrypt.MlKemFreeKey(ref keyA);
824+
if (ret != 0)
825+
{
826+
Console.Error.WriteLine($"Failed to free MlKem key A. Error code: {ret}");
827+
}
828+
}
829+
if (keyB != IntPtr.Zero)
830+
{
831+
ret = wolfcrypt.MlKemFreeKey(ref keyB);
832+
if (ret != 0)
833+
{
834+
Console.Error.WriteLine($"Failed to free MlKem key B. Error code: {ret}");
835+
}
836+
}
837+
}
838+
} /* END mlkem_test */
839+
840+
private static void mldsa_test(wolfcrypt.MlDsaTypes type)
841+
{
842+
int ret = 0;
843+
IntPtr key = IntPtr.Zero;
844+
IntPtr heap = IntPtr.Zero;
845+
int devId = wolfcrypt.INVALID_DEVID;
846+
byte[] privateKey = null;
847+
byte[] publicKey = null;
848+
byte[] message = Encoding.UTF8.GetBytes("This is some data to sign with ML-DSA");
849+
byte[] signature = null;
850+
851+
try
852+
{
853+
Console.WriteLine("\nStarting " + type + " shared secret test ...");
854+
855+
/* Generate Key */
856+
Console.WriteLine("Testing ML-DSA Key Generation...");
857+
key = wolfcrypt.DilithiumMakeKey(heap, devId, type);
858+
if (key == IntPtr.Zero)
859+
{
860+
ret = -1;
861+
Console.Error.WriteLine("Failed to generate keypair.");
862+
}
863+
if (ret == 0)
864+
{
865+
Console.WriteLine("ML-DSA Key Generation test passed.");
866+
}
867+
868+
/* Export */
869+
if (ret == 0)
870+
{
871+
Console.WriteLine("Testing ML-DSA Key Export...");
872+
ret = DilithiumExportPrivateKey(key, out privateKey);
873+
if (ret != 0)
874+
{
875+
Console.Error.WriteLine($"Failed to export private key. Error code: {ret}");
876+
}
877+
}
878+
if (ret == 0)
879+
{
880+
ret = DilithiumExportPublicKey(key, out publicKey);
881+
if (ret != 0)
882+
{
883+
Console.Error.WriteLine($"Failed to export public key. Error code: {ret}");
884+
}
885+
}
886+
if (ret == 0)
887+
{
888+
Console.WriteLine("ML-DSA Key Export test passed.");
889+
}
890+
891+
/* Import */
892+
if (ret == 0)
893+
{
894+
Console.WriteLine("Testing ML-DSA Key Import...");
895+
ret = DilithiumImportPrivateKey(privateKey, key);
896+
if (ret != 0)
897+
{
898+
Console.Error.WriteLine($"Failed to import private key. Error code: {ret}");
899+
}
900+
}
901+
if (ret == 0)
902+
{
903+
ret = DilithiumImportPublicKey(publicKey, key);
904+
if (ret != 0)
905+
{
906+
Console.Error.WriteLine($"Failed to import public key. Error code: {ret}");
907+
}
908+
}
909+
if (ret == 0)
910+
{
911+
Console.WriteLine("ML-DSA Key Import test passed.");
912+
}
913+
914+
/* Sign */
915+
if (ret == 0)
916+
{
917+
Console.WriteLine("Testing ML-DSA Signature Creation...");
918+
ret = wolfcrypt.DilithiumSignMsg(key, message, out signature);
919+
if (ret != 0)
920+
{
921+
Console.Error.WriteLine($"Failed to sign. Error code: {ret}");
922+
}
923+
}
924+
if (ret == 0)
925+
{
926+
Console.WriteLine($"ML-DSA Signature Creation test passed. Signature Length: {signature.Length}");
927+
}
928+
929+
/* Verify */
930+
if (ret == 0)
931+
{
932+
Console.WriteLine("Testing ML-DSA Signature Verification...");
933+
ret = wolfcrypt.DilithiumVerifyMsg(key, message, signature);
934+
if (ret != 0)
935+
{
936+
Console.Error.WriteLine($"Failed to verify message. Error code: {ret}");
937+
}
938+
}
939+
if (ret == 0)
940+
{
941+
Console.WriteLine("ML-DSA Signature Verification test passed.");
942+
}
943+
944+
if (ret != 0)
945+
{
946+
throw new Exception("ML-DSA test failed.");
947+
}
948+
}
949+
catch (Exception ex)
950+
{
951+
Console.WriteLine($"ML-DSA test failed: {ex.Message}");
952+
}
953+
finally
954+
{
955+
if (key != IntPtr.Zero)
956+
{
957+
ret = wolfcrypt.DilithiumFreeKey(ref key);
958+
if (ret != 0)
959+
{
960+
Console.Error.WriteLine($"Failed to free Dilithium key. Error code: {ret}");
961+
}
962+
}
963+
}
964+
965+
} /* END mldsa_test */
966+
677967
private static void aes_gcm_test()
678968
{
679969
IntPtr aes = IntPtr.Zero;
@@ -930,6 +1220,18 @@ public static void Main(string[] args)
9301220

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

1223+
Console.WriteLine("\nStarting ML-KEM test");
1224+
1225+
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_512); /* ML-KEM test */
1226+
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_768); /* ML-KEM test */
1227+
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_1024); /* ML-KEM test */
1228+
1229+
Console.WriteLine("\nStarting ML-DSA test");
1230+
1231+
mldsa_test(wolfcrypt.MlDsaTypes.ML_DSA_44); /* ML-DSA test */
1232+
mldsa_test(wolfcrypt.MlDsaTypes.ML_DSA_65); /* ML-DSA test */
1233+
mldsa_test(wolfcrypt.MlDsaTypes.ML_DSA_87); /* ML-DSA test */
1234+
9331235
Console.WriteLine("\nStarting AES-GCM test");
9341236

9351237
aes_gcm_test(); /* AES_GCM test */

0 commit comments

Comments
 (0)