Skip to content

Commit a77c646

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

File tree

4 files changed

+1128
-0
lines changed

4 files changed

+1128
-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: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,201 @@ 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;
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+
Console.Error.WriteLine("Failed to generate key pair A.");
672+
}
673+
674+
Console.WriteLine("Generate Key Pair B...");
675+
keyB = wolfcrypt.MlKemMakeKey(type, heap, devId);
676+
if (keyB == IntPtr.Zero)
677+
{
678+
Console.Error.WriteLine("Failed to generate key pair B.");
679+
}
680+
681+
Console.WriteLine("ML-KEM Key Generation test passed.");
682+
683+
/* Encode */
684+
Console.WriteLine("Testing ML-KEM Key Encode...");
685+
ret = wolfcrypt.MlKemEncodePublicKey(keyA, out pubA);
686+
if (ret != 0)
687+
{
688+
Console.Error.WriteLine("Failed to encode public key of A.");
689+
}
690+
ret = wolfcrypt.MlKemEncodePrivateKey(keyA, out privA);
691+
if (ret != 0)
692+
{
693+
Console.Error.WriteLine("Failed to encode private key of A.");
694+
}
695+
Console.WriteLine("ML-KEM Key Encode test passed.");
696+
697+
/* Encapsulate */
698+
Console.WriteLine("Testing ML-KEM Encapsulation...");
699+
ret = wolfcrypt.MlKemEncapsulate(keyA, out cipherText, out sharedSecretA);
700+
if (ret != 0)
701+
{
702+
Console.Error.WriteLine("Failed to encapsulate.");
703+
}
704+
Console.WriteLine("ML-KEM Encapsulation test passed.");
705+
706+
/* Decode */
707+
Console.WriteLine("Testing ML-KEM Decode...");
708+
ret = wolfcrypt.MlKemDecodePrivateKey(keyB, privA);
709+
if (ret != 0)
710+
{
711+
Console.Error.WriteLine("Failed to decode private key of A.");
712+
}
713+
ret = wolfcrypt.MlKemDecodePublicKey(keyB, pubA);
714+
if (ret != 0)
715+
{
716+
Console.Error.WriteLine("Failed to decode public key of B.");
717+
}
718+
Console.WriteLine("ML-KEM Decode test passed.");
719+
720+
/* Decapsulate */
721+
Console.WriteLine("Testing ML-KEM Decapsulation...");
722+
ret = wolfcrypt.MlKemDecapsulate(keyB, cipherText, out sharedSecretB);
723+
if (ret != 0)
724+
{
725+
Console.Error.WriteLine("Failed to decapsulate.");
726+
}
727+
Console.WriteLine("ML-KEM Decapsulation test passed.");
728+
729+
/* Check */
730+
Console.WriteLine("Comparing Shared Secrets...");
731+
if (!wolfcrypt.ByteArrayVerify(sharedSecretA, sharedSecretB))
732+
{
733+
Console.Error.WriteLine("Shared secrets do not match.");
734+
}
735+
else
736+
{
737+
Console.WriteLine("ML-KEM shared secret match.");
738+
}
739+
}
740+
finally
741+
{
742+
/* Cleanup */
743+
if (keyA != IntPtr.Zero)
744+
{
745+
ret = wolfcrypt.MlKemFreeKey(keyA);
746+
if (ret != 0)
747+
{
748+
Console.Error.WriteLine("Failed to free MlKem key A. Error code: " + ret);
749+
}
750+
}
751+
if (keyB != IntPtr.Zero)
752+
{
753+
ret = wolfcrypt.MlKemFreeKey(keyB);
754+
if (ret != 0)
755+
{
756+
Console.Error.WriteLine("Failed to free MlKem key B. Error code: " + ret);
757+
}
758+
}
759+
}
760+
} /* END mlkem_test */
761+
762+
private static void mldsa_test(wolfcrypt.MlDsaTypes type)
763+
{
764+
int ret;
765+
IntPtr key = IntPtr.Zero;
766+
IntPtr heap = IntPtr.Zero;
767+
int devId = wolfcrypt.INVALID_DEVID;
768+
byte[] privateKey;
769+
byte[] publicKey;
770+
byte[] message = Encoding.UTF8.GetBytes("This is some data to sign with ML-DSA");
771+
byte[] signature;
772+
773+
try
774+
{
775+
Console.WriteLine("\nStarting " + type + " shared secret test ...");
776+
777+
/* Generate Key Pair */
778+
Console.WriteLine("Testing ML-DSA Key Generation...");
779+
key = wolfcrypt.DilithiumMakeKey(heap, devId, type);
780+
if (key == IntPtr.Zero)
781+
{
782+
Console.Error.WriteLine("DilithiumMakeKey failed");
783+
}
784+
Console.WriteLine("ML-DSA Key Generation test passed.");
785+
786+
/* Export */
787+
Console.WriteLine("Testing ML-DSA Key Export...");
788+
ret = DilithiumExportPrivateKey(key, out privateKey);
789+
if (ret != 0)
790+
{
791+
Console.Error.WriteLine("DilithiumExportPrivateKey failed");
792+
}
793+
ret = DilithiumExportPublicKey(key, out publicKey);
794+
if (ret != 0)
795+
{
796+
Console.Error.WriteLine("DilithiumExportPublicKey failed");
797+
}
798+
Console.WriteLine("ML-DSA Key Export test passed.");
799+
800+
/* Import */
801+
Console.WriteLine("Testing ML-DSA Key Import...");
802+
ret = DilithiumImportPrivateKey(privateKey, key);
803+
if (ret != 0)
804+
{
805+
Console.Error.WriteLine("DilithiumImportPrivateKey failed");
806+
}
807+
ret = DilithiumImportPublicKey(publicKey, key);
808+
if (ret != 0)
809+
{
810+
Console.Error.WriteLine("DilithiumImportPrivateKey failed");
811+
}
812+
Console.WriteLine("ML-DSA Key Import test passed.");
813+
814+
/* Sign */
815+
Console.WriteLine("Testing ML-DSA Signature Creation...");
816+
ret = wolfcrypt.DilithiumSignMsg(key, message, out signature);
817+
if (ret != 0)
818+
{
819+
Console.Error.WriteLine("DilithiumSign failed");
820+
}
821+
Console.WriteLine($"ML-DSA Signature Creation test passed. Signature Length: {signature.Length}");
822+
823+
/* Verify */
824+
Console.WriteLine("Testing ML-DSA Signature Verification...");
825+
ret = wolfcrypt.DilithiumVerifyMsg(key, message, signature);
826+
if (ret != 0)
827+
{
828+
Console.Error.WriteLine("DilithiumVerify failed");
829+
}
830+
Console.WriteLine("ML-DSA Signature Verification test passed.");
831+
}
832+
finally
833+
{
834+
if (key != IntPtr.Zero)
835+
{
836+
ret = wolfcrypt.DilithiumFreeKey(key);
837+
if (ret != 0)
838+
{
839+
Console.Error.WriteLine("Failed to free Dilithium key. Error code: " + ret);
840+
}
841+
}
842+
}
843+
844+
} /* END mldsa_test */
845+
651846
private static void aes_gcm_test()
652847
{
653848
IntPtr aes = IntPtr.Zero;
@@ -904,6 +1099,18 @@ public static void Main(string[] args)
9041099

9051100
curve25519_test(); /* curve25519 shared secret test */
9061101

1102+
Console.WriteLine("\nStarting ML-KEM test");
1103+
1104+
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_512); /* ML-KEM test */
1105+
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_768); /* ML-KEM test */
1106+
mlkem_test(wolfcrypt.MlKemTypes.ML_KEM_1024); /* ML-KEM test */
1107+
1108+
Console.WriteLine("\nStarting ML-DSA test");
1109+
1110+
mldsa_test(wolfcrypt.MlDsaTypes.ML_DSA_44); /* ML-DSA test */
1111+
mldsa_test(wolfcrypt.MlDsaTypes.ML_DSA_65); /* ML-DSA test */
1112+
mldsa_test(wolfcrypt.MlDsaTypes.ML_DSA_87); /* ML-DSA test */
1113+
9071114
Console.WriteLine("\nStarting AES-GCM test");
9081115

9091116
aes_gcm_test(); /* AES_GCM test */

0 commit comments

Comments
 (0)