@@ -78,6 +78,52 @@ mod tests {
7878 . await
7979 }
8080
81+ /// The official SHAKE256 PQ suites (0xF001-0xF009), now driven end to end by the
82+ /// SHAKE256 one-shot key schedule. One classical-signature variant (Ed25519, 0xF001)
83+ /// and one ML-DSA variant (ML-DSA-65, 0xF008), so a full PQ group gets exercised.
84+ #[ rstest:: rstest]
85+ #[ case:: ed25519( openmls:: prelude:: Ciphersuite :: MLS_128_MLKEM768X25519_AES128GCM_SHA256_Ed25519 ) ]
86+ #[ case:: mldsa65( openmls:: prelude:: Ciphersuite :: MLS_192_MLKEM768_AES256GCM_SHA384_MLDSA65 ) ]
87+ #[ test_attr( macro_rules_attribute:: apply( smol_macros:: test) ) ]
88+ async fn official_pq_suite_full_conversation_roundtrip ( #[ case] ciphersuite : openmls:: prelude:: Ciphersuite ) {
89+ let case = TestContext :: new ( CredentialType :: Basic , ciphersuite) ;
90+ let [ alice, bob] = case. sessions ( ) . await ;
91+ Box :: pin ( async move {
92+ // create + add: alice creates the conversation and invites bob
93+ let conversation = case. create_conversation ( [ & alice, & bob] ) . await ;
94+ assert_eq ! ( conversation. member_count( ) . await , 2 ) ;
95+
96+ // app-message round-trip: alice -> bob
97+ let msg = b"Hello bob, this is a post-quantum greeting" ;
98+ let encrypted = conversation. guard ( ) . await . encrypt_message ( msg) . await . unwrap ( ) ;
99+ assert_ne ! ( & msg[ ..] , & encrypted[ ..] ) ;
100+ let decrypted = conversation
101+ . guard_of ( & bob)
102+ . await
103+ . decrypt_message ( encrypted)
104+ . await
105+ . unwrap ( )
106+ . app_msg
107+ . unwrap ( ) ;
108+ assert_eq ! ( & decrypted[ ..] , & msg[ ..] ) ;
109+
110+ // app-message round-trip: bob -> alice
111+ let reply = b"Hello alice, post-quantum reply received" ;
112+ let encrypted = conversation. guard_of ( & bob) . await . encrypt_message ( reply) . await . unwrap ( ) ;
113+ assert_ne ! ( & reply[ ..] , & encrypted[ ..] ) ;
114+ let decrypted = conversation
115+ . guard ( )
116+ . await
117+ . decrypt_message ( encrypted)
118+ . await
119+ . unwrap ( )
120+ . app_msg
121+ . unwrap ( ) ;
122+ assert_eq ! ( & decrypted[ ..] , & reply[ ..] ) ;
123+ } )
124+ . await
125+ }
126+
81127 // Ensures encrypting an application message is durable
82128 #[ apply( all_cred_cipher) ]
83129 async fn can_encrypt_consecutive_messages ( case : TestContext ) {
0 commit comments