@@ -45,6 +45,10 @@ mod kem_params {
4545 pub const MLKEM768_ID : u16 = 0x0041 ;
4646 pub const MLKEM768_NSECRET : usize = 32 ;
4747 pub const MLKEM768_NENC : usize = 1088 ;
48+
49+ pub const MLKEM1024_ID : u16 = 0x0042 ;
50+ pub const MLKEM1024_NSECRET : usize = 32 ;
51+ pub const MLKEM1024_NENC : usize = 1568 ;
4852}
4953
5054mod kdf_params {
@@ -89,6 +93,7 @@ pub(crate) enum KEM {
8993 P384 ,
9094 P521 ,
9195 MLKEM768 ,
96+ MLKEM1024 ,
9297}
9398
9499impl KEM {
@@ -153,6 +158,7 @@ impl KEM {
153158 KEM :: P384 => kem_params:: P384_ID ,
154159 KEM :: P521 => kem_params:: P521_ID ,
155160 KEM :: MLKEM768 => kem_params:: MLKEM768_ID ,
161+ KEM :: MLKEM1024 => kem_params:: MLKEM1024_ID ,
156162 }
157163 }
158164
@@ -163,6 +169,7 @@ impl KEM {
163169 KEM :: P384 => kem_params:: P384_NSECRET ,
164170 KEM :: P521 => kem_params:: P521_NSECRET ,
165171 KEM :: MLKEM768 => kem_params:: MLKEM768_NSECRET ,
172+ KEM :: MLKEM1024 => kem_params:: MLKEM1024_NSECRET ,
166173 }
167174 }
168175
@@ -173,6 +180,7 @@ impl KEM {
173180 KEM :: P384 => kem_params:: P384_NENC ,
174181 KEM :: P521 => kem_params:: P521_NENC ,
175182 KEM :: MLKEM768 => kem_params:: MLKEM768_NENC ,
183+ KEM :: MLKEM1024 => kem_params:: MLKEM1024_NENC ,
176184 }
177185 }
178186
@@ -221,6 +229,15 @@ impl KEM {
221229 ) ) ;
222230 }
223231 }
232+ KEM :: MLKEM1024 => {
233+ if !key. is_instance ( & types:: MLKEM1024_PUBLIC_KEY . get ( py) ?) ? {
234+ return Err ( CryptographyError :: from (
235+ pyo3:: exceptions:: PyTypeError :: new_err (
236+ "Expected MLKEM1024PublicKey for KEM.MLKEM1024" ,
237+ ) ,
238+ ) ) ;
239+ }
240+ }
224241 }
225242 Ok ( ( ) )
226243 }
@@ -270,6 +287,15 @@ impl KEM {
270287 ) ) ;
271288 }
272289 }
290+ KEM :: MLKEM1024 => {
291+ if !key. is_instance ( & types:: MLKEM1024_PRIVATE_KEY . get ( py) ?) ? {
292+ return Err ( CryptographyError :: from (
293+ pyo3:: exceptions:: PyTypeError :: new_err (
294+ "Expected MLKEM1024PrivateKey for KEM.MLKEM1024" ,
295+ ) ,
296+ ) ) ;
297+ }
298+ }
273299 }
274300 Ok ( ( ) )
275301 }
@@ -284,7 +310,7 @@ impl KEM {
284310 pyo3:: Bound < ' p , pyo3:: types:: PyBytes > ,
285311 ) > {
286312 match self {
287- KEM :: MLKEM768 => {
313+ KEM :: MLKEM768 | KEM :: MLKEM1024 => {
288314 let result = pk_r. call_method0 ( pyo3:: intern!( py, "encapsulate" ) ) ?;
289315 Ok ( result. extract ( ) ?)
290316 }
@@ -302,7 +328,7 @@ impl KEM {
302328 kem_suite_id : & [ u8 ; 5 ] ,
303329 ) -> CryptographyResult < pyo3:: Bound < ' p , pyo3:: types:: PyBytes > > {
304330 match self {
305- KEM :: MLKEM768 => {
331+ KEM :: MLKEM768 | KEM :: MLKEM1024 => {
306332 let enc_bytes = pyo3:: types:: PyBytes :: new ( py, enc) ;
307333 Ok ( sk_r
308334 . call_method1 ( pyo3:: intern!( py, "decapsulate" ) , ( enc_bytes, ) ) ?
@@ -446,8 +472,8 @@ impl KEM {
446472 . into_any ( ) ,
447473 )
448474 }
449- KEM :: MLKEM768 => {
450- unreachable ! ( "ML-KEM-768 does not generate an ephemeral DH key" )
475+ KEM :: MLKEM768 | KEM :: MLKEM1024 => {
476+ unreachable ! ( "ML-KEM does not generate an ephemeral DH key" )
451477 }
452478 }
453479 }
@@ -470,8 +496,8 @@ impl KEM {
470496 ) ,
471497 ) ?
472498 . extract ( ) ?) ,
473- KEM :: MLKEM768 => {
474- unreachable ! ( "ML-KEM-768 public keys are not serialized via this path" )
499+ KEM :: MLKEM768 | KEM :: MLKEM1024 => {
500+ unreachable ! ( "ML-KEM public keys are not serialized via this path" )
475501 }
476502 }
477503 }
@@ -495,8 +521,8 @@ impl KEM {
495521 let secp521r1 = types:: SECP521R1 . get ( py) ?. call0 ( ) ?;
496522 Ok ( pyo3:: Bound :: new ( py, ec:: from_public_bytes ( py, secp521r1, data) ?) ?. into_any ( ) )
497523 }
498- KEM :: MLKEM768 => {
499- unreachable ! ( "ML-KEM-768 encapsulated key is a ciphertext, not a public key" )
524+ KEM :: MLKEM768 | KEM :: MLKEM1024 => {
525+ unreachable ! ( "ML-KEM encapsulated key is a ciphertext, not a public key" )
500526 }
501527 }
502528 }
@@ -515,8 +541,8 @@ impl KEM {
515541 let ecdh = types:: ECDH . get ( py) ?. call0 ( ) ?;
516542 Ok ( private_key. call_method1 ( pyo3:: intern!( py, "exchange" ) , ( & ecdh, public_key) ) ?)
517543 }
518- KEM :: MLKEM768 => {
519- unreachable ! ( "ML-KEM-768 does not perform a Diffie-Hellman exchange" )
544+ KEM :: MLKEM768 | KEM :: MLKEM1024 => {
545+ unreachable ! ( "ML-KEM does not perform a Diffie-Hellman exchange" )
520546 }
521547 }
522548 }
@@ -529,8 +555,8 @@ impl KEM {
529555 KEM :: X25519 | KEM :: P256 => Ok ( types:: SHA256 . get ( py) ?. call0 ( ) ?) ,
530556 KEM :: P384 => Ok ( types:: SHA384 . get ( py) ?. call0 ( ) ?) ,
531557 KEM :: P521 => Ok ( types:: SHA512 . get ( py) ?. call0 ( ) ?) ,
532- KEM :: MLKEM768 => {
533- unreachable ! ( "ML-KEM-768 does not use a KEM hash algorithm" )
558+ KEM :: MLKEM768 | KEM :: MLKEM1024 => {
559+ unreachable ! ( "ML-KEM does not use a KEM hash algorithm" )
534560 }
535561 }
536562 }
@@ -994,7 +1020,15 @@ mod tests {
9941020 }
9951021
9961022 #[ test]
997- #[ should_panic( expected = "ML-KEM-768 does not generate an ephemeral DH key" ) ]
1023+ fn test_mlkem1024_secret_length ( ) {
1024+ assert_eq ! (
1025+ KEM :: MLKEM1024 . secret_length( ) ,
1026+ kem_params:: MLKEM1024_NSECRET
1027+ ) ;
1028+ }
1029+
1030+ #[ test]
1031+ #[ should_panic( expected = "ML-KEM does not generate an ephemeral DH key" ) ]
9981032 fn test_mlkem768_generate_key_unreachable ( ) {
9991033 pyo3:: Python :: initialize ( ) ;
10001034
@@ -1004,7 +1038,7 @@ mod tests {
10041038 }
10051039
10061040 #[ test]
1007- #[ should_panic( expected = "ML-KEM-768 public keys are not serialized via this path" ) ]
1041+ #[ should_panic( expected = "ML-KEM public keys are not serialized via this path" ) ]
10081042 fn test_mlkem768_serialize_public_key_unreachable ( ) {
10091043 pyo3:: Python :: initialize ( ) ;
10101044
@@ -1015,7 +1049,7 @@ mod tests {
10151049 }
10161050
10171051 #[ test]
1018- #[ should_panic( expected = "ML-KEM-768 encapsulated key is a ciphertext, not a public key" ) ]
1052+ #[ should_panic( expected = "ML-KEM encapsulated key is a ciphertext, not a public key" ) ]
10191053 fn test_mlkem768_deserialize_public_key_unreachable ( ) {
10201054 pyo3:: Python :: initialize ( ) ;
10211055
@@ -1025,7 +1059,7 @@ mod tests {
10251059 }
10261060
10271061 #[ test]
1028- #[ should_panic( expected = "ML-KEM-768 does not perform a Diffie-Hellman exchange" ) ]
1062+ #[ should_panic( expected = "ML-KEM does not perform a Diffie-Hellman exchange" ) ]
10291063 fn test_mlkem768_exchange_unreachable ( ) {
10301064 pyo3:: Python :: initialize ( ) ;
10311065
@@ -1036,7 +1070,7 @@ mod tests {
10361070 }
10371071
10381072 #[ test]
1039- #[ should_panic( expected = "ML-KEM-768 does not use a KEM hash algorithm" ) ]
1073+ #[ should_panic( expected = "ML-KEM does not use a KEM hash algorithm" ) ]
10401074 fn test_mlkem768_kem_hash_algorithm_unreachable ( ) {
10411075 pyo3:: Python :: initialize ( ) ;
10421076
0 commit comments