diff --git a/native/cpp/CommonCpp/CryptoTools/CryptoModule.h b/native/cpp/CommonCpp/CryptoTools/CryptoModule.h
--- a/native/cpp/CommonCpp/CryptoTools/CryptoModule.h
+++ b/native/cpp/CommonCpp/CryptoTools/CryptoModule.h
@@ -77,6 +77,9 @@
   encrypt(const std::string &targetDeviceId, const std::string &content);
   std::string
   decrypt(const std::string &targetDeviceId, EncryptedData &encryptedData);
+  std::string decryptSequential(
+      const std::string &targetDeviceId,
+      EncryptedData &encryptedData);
 
   std::string signMessage(const std::string &message);
   static void verifySignature(
diff --git a/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp b/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp
--- a/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp
+++ b/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp
@@ -414,6 +414,16 @@
   return this->sessions.at(targetDeviceId)->decrypt(encryptedData);
 }
 
+std::string CryptoModule::decryptSequential(
+    const std::string &targetDeviceId,
+    EncryptedData &encryptedData) {
+  if (!this->hasSessionFor(targetDeviceId)) {
+    throw std::runtime_error{
+        "error decrypt sequential => uninitialized session"};
+  }
+  return this->sessions.at(targetDeviceId)->decryptSequential(encryptedData);
+}
+
 std::string CryptoModule::signMessage(const std::string &message) {
   OlmBuffer signature;
   signature.resize(::olm_account_signature_length(this->getOlmAccount()));
diff --git a/native/cpp/CommonCpp/CryptoTools/Session.h b/native/cpp/CommonCpp/CryptoTools/Session.h
--- a/native/cpp/CommonCpp/CryptoTools/Session.h
+++ b/native/cpp/CommonCpp/CryptoTools/Session.h
@@ -32,6 +32,7 @@
   restoreFromB64(const std::string &secretKey, OlmBuffer &b64);
   OlmSession *getOlmSession();
   std::string decrypt(EncryptedData &encryptedData);
+  std::string decryptSequential(EncryptedData &encryptedData);
   int getVersion();
   void setVersion(int newVersion);
 };
diff --git a/native/cpp/CommonCpp/CryptoTools/Session.cpp b/native/cpp/CommonCpp/CryptoTools/Session.cpp
--- a/native/cpp/CommonCpp/CryptoTools/Session.cpp
+++ b/native/cpp/CommonCpp/CryptoTools/Session.cpp
@@ -157,6 +157,51 @@
   return std::string{(char *)decryptedMessage.data(), decryptedSize};
 }
 
+std::string Session::decryptSequential(EncryptedData &encryptedData) {
+  OlmSession *session = this->getOlmSession();
+
+  OlmBuffer utilityBuffer(::olm_utility_size());
+  OlmUtility *olmUtility = ::olm_utility(utilityBuffer.data());
+
+  OlmBuffer messageHashBuffer(::olm_sha256_length(olmUtility));
+  ::olm_sha256(
+      olmUtility,
+      encryptedData.message.data(),
+      encryptedData.message.size(),
+      messageHashBuffer.data(),
+      messageHashBuffer.size());
+
+  OlmBuffer tmpEncryptedMessage(encryptedData.message);
+  size_t maxSize = ::olm_decrypt_max_plaintext_length(
+      session,
+      encryptedData.messageType,
+      tmpEncryptedMessage.data(),
+      tmpEncryptedMessage.size());
+
+  if (maxSize == -1) {
+    throw std::runtime_error{
+        "error decrypt_max_plaintext_length => " +
+        std::string{::olm_session_last_error(session)} + ". Hash: " +
+        std::string{messageHashBuffer.begin(), messageHashBuffer.end()}};
+  }
+
+  OlmBuffer decryptedMessage(maxSize);
+  size_t decryptedSize = ::olm_decrypt_sequential(
+      session,
+      encryptedData.messageType,
+      encryptedData.message.data(),
+      encryptedData.message.size(),
+      decryptedMessage.data(),
+      decryptedMessage.size());
+  if (decryptedSize == -1) {
+    throw std::runtime_error{
+        "error decrypt_sequential => " +
+        std::string{::olm_session_last_error(session)} + ". Hash: " +
+        std::string{messageHashBuffer.begin(), messageHashBuffer.end()}};
+  }
+  return std::string{(char *)decryptedMessage.data(), decryptedSize};
+}
+
 int Session::getVersion() {
   return this->version;
 }