From 459be02d18d8e9b2c7a838a956d5d437a3f1f80a Mon Sep 17 00:00:00 2001
From: orignal <i2porignal@yandex.ru>
Date: Mon, 14 Apr 2025 13:31:37 -0400
Subject: [PATCH] correct sequence of MixKey for ML-KEM NSR

---
 libi2pd/ECIESX25519AEADRatchetSession.cpp | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp
index de95ce00..d5b7150d 100644
--- a/libi2pd/ECIESX25519AEADRatchetSession.cpp
+++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp
@@ -649,13 +649,6 @@ namespace garlic
 			return false;
 		}
 		MixKey (sharedSecret);
-		if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // sharedSecret = x25519(besk, apk)
-		{
-			LogPrint (eLogWarning, "Garlic: Incorrect Alice static key");
-			return false;
-		}
-		MixKey (sharedSecret);
-		
 #if OPENSSL_PQ
 		if (m_PQKeys)
 		{
@@ -675,6 +668,12 @@ namespace garlic
 			offset += cipherTextLen + 16;
 		}	
 #endif		
+		if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // sharedSecret = x25519(besk, apk)
+		{
+			LogPrint (eLogWarning, "Garlic: Incorrect Alice static key");
+			return false;
+		}
+		MixKey (sharedSecret);
 		// calculate hash for zero length
 		if (!Encrypt (sharedSecret /* can be anything */, out + offset, 0)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad)
 		{
@@ -778,9 +777,6 @@ namespace garlic
 			return false;
 		}
 		MixKey (sharedSecret);
-		GetOwner ()->Decrypt (bepk, sharedSecret, m_RemoteStaticKeyType); // x25519 (ask, bepk)
-		MixKey (sharedSecret);
-
 #if OPENSSL_PQ
 		if (m_RemoteStaticKeyType >= i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD)
 		{
@@ -799,7 +795,10 @@ namespace garlic
 			m_PQKeys->Decaps (kemCiphertext.data (), sharedSecret);
 			MixKey (sharedSecret);
 		}
-#endif		
+#endif	
+		GetOwner ()->Decrypt (bepk, sharedSecret, m_RemoteStaticKeyType); // x25519 (ask, bepk)
+		MixKey (sharedSecret);
+		
 		// calculate hash for zero length
 		if (!Decrypt (buf, sharedSecret/* can be anything */, 0)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only
 		{