Skip to content

Commit 17a6bf3

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

4 files changed

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

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

1213+
Console.WriteLine("\nStarting ML-KEM test");
1214+
1215+
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_512); /* ML-KEM test */
1216+
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_768); /* ML-KEM test */
1217+
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_1024); /* ML-KEM test */
1218+
1219+
Console.WriteLine("\nStarting ML-DSA test");
1220+
1221+
mldsa_test(wolfcrypt.MlDsaTypes.ML_DSA_44); /* ML-DSA test */
1222+
mldsa_test(wolfcrypt.MlDsaTypes.ML_DSA_65); /* ML-DSA test */
1223+
mldsa_test(wolfcrypt.MlDsaTypes.ML_DSA_87); /* ML-DSA test */
1224+
9331225
Console.WriteLine("\nStarting AES-GCM test");
9341226

9351227
aes_gcm_test(); /* AES_GCM test */

0 commit comments

Comments
 (0)