private byte[] Decrypt(SessionState sessionState, SignalMessage ciphertextMessage) { if (!sessionState.HasSenderChain()) { throw new InvalidMessageException("Uninitialized session!"); } if (ciphertextMessage.GetMessageVersion() != sessionState.GetSessionVersion()) { throw new InvalidMessageException($"Message version {ciphertextMessage.GetMessageVersion()}, but session version {sessionState.GetSessionVersion()}"); } uint messageVersion = ciphertextMessage.GetMessageVersion(); IEcPublicKey theirEphemeral = ciphertextMessage.GetSenderRatchetKey(); uint counter = ciphertextMessage.GetCounter(); ChainKey chainKey = GetOrCreateChainKey(sessionState, theirEphemeral); MessageKeys messageKeys = GetOrCreateMessageKeys(sessionState, theirEphemeral, chainKey, counter); ciphertextMessage.VerifyMac(messageVersion, sessionState.GetRemoteIdentityKey(), sessionState.GetLocalIdentityKey(), messageKeys.GetMacKey()); byte[] plaintext = GetPlaintext(messageVersion, messageKeys, ciphertextMessage.GetBody()); sessionState.ClearUnacknowledgedPreKeyMessage(); return(plaintext); }