Skip to content

Commit 7a6dc26

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

4 files changed

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

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

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

9351238
aes_gcm_test(); /* AES_GCM test */

0 commit comments

Comments
 (0)