diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp
index 711d4ce6..1c362c3b 100644
--- a/libi2pd/CryptoKey.cpp
+++ b/libi2pd/CryptoKey.cpp
@@ -1,6 +1,7 @@
 #include <string.h>
 #include "Log.h"
 #include "Gost.h"
+#include "Elligator.h"
 #include "CryptoKey.h"
 
 namespace i2p
@@ -146,6 +147,22 @@ namespace crypto
 		BN_free (x); BN_free (y);
 	}
 
+
+	bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * keyMaterial, BN_CTX * ctx, bool zeroPadding)
+	{
+		uint8_t key[32];
+		if (!GetElligator ()->Decode (epub, key)) return false;
+		m_StaticKeys.Agree (key, keyMaterial);
+		return true; 
+	}
+
+	void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub)
+	{
+		X25519Keys k;
+		k.GenerateKeys ();		
+		k.GetPrivateKey (priv);
+		memcpy (pub, k.GetPublicKey (), 32);
+	}
 }
 }
 
diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h
index 5584b687..c4788959 100644
--- a/libi2pd/CryptoKey.h
+++ b/libi2pd/CryptoKey.h
@@ -116,6 +116,25 @@ namespace crypto
 	};
 
 	void CreateECIESGOSTR3410RandomKeys (uint8_t * priv, uint8_t * pub);
+
+// ECIES-X25519-AEAD-Ratchet
+
+	class ECIESX25519AEADRatchetDecryptor: public CryptoKeyDecryptor
+	{
+		public:
+
+			ECIESX25519AEADRatchetDecryptor (const uint8_t * priv): m_StaticKeys (priv, nullptr) {};
+			~ECIESX25519AEADRatchetDecryptor () {};
+			bool Decrypt (const uint8_t * epub, uint8_t * keyMaterial, BN_CTX * ctx, bool zeroPadding); 
+			// take elligator encoded ephemeral pub (32 bytes), agree with static and return in keyMaterial (32 bytes)
+			size_t GetPublicKeyLen () const { return 32; };
+
+		private:
+
+			X25519Keys m_StaticKeys;
+	};
+
+	void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub);
 }
 }
 
diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp
index f088d3f2..d217f41d 100644
--- a/libi2pd/Identity.cpp
+++ b/libi2pd/Identity.cpp
@@ -674,6 +674,9 @@ namespace data
 			case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC:
 				return std::make_shared<i2p::crypto::ECIESGOSTR3410Decryptor>(key);
 			break;
+			case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET:
+				return std::make_shared<i2p::crypto::ECIESX25519AEADRatchetDecryptor>(key);
+			break;
 			default:
 				LogPrint (eLogError, "Identity: Unknown crypto key type ", (int)cryptoType);
 		};
@@ -750,6 +753,9 @@ namespace data
 			case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC:
 				i2p::crypto::CreateECIESGOSTR3410RandomKeys (priv, pub);
 			break;
+			case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET:
+				i2p::crypto::CreateECIESX25519AEADRatchetRandomKeys (priv, pub);
+			break;
 			default:
 				LogPrint (eLogError, "Identity: Crypto key type ", (int)type, " is not supported");
 		}
diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h
index 72fd14c5..2fecc28a 100644
--- a/libi2pd/Identity.h
+++ b/libi2pd/Identity.h
@@ -55,6 +55,7 @@ namespace data
 
 	const uint16_t CRYPTO_KEY_TYPE_ELGAMAL = 0;
 	const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC = 1;
+	const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET = 4; 	
 	const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST = 65280; // TODO: remove later
 	const uint16_t CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC = 65281; // TODO: use GOST R 34.11 instead SHA256 and GOST 28147-89 instead AES