TDesu.Telegram.Crypto 0.2.0

dotnet add package TDesu.Telegram.Crypto --version 0.2.0
                    
NuGet\Install-Package TDesu.Telegram.Crypto -Version 0.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TDesu.Telegram.Crypto" Version="0.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TDesu.Telegram.Crypto" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="TDesu.Telegram.Crypto" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add TDesu.Telegram.Crypto --version 0.2.0
                    
#r "nuget: TDesu.Telegram.Crypto, 0.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package TDesu.Telegram.Crypto@0.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=TDesu.Telegram.Crypto&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=TDesu.Telegram.Crypto&version=0.2.0
                    
Install as a Cake Tool

TDesu.Telegram.Crypto

NuGet License: Unlicense

Cryptographic primitives for Telegram MTProto 2.0. AES-IGE, Diffie-Hellman key exchange, RSA encryption, and key derivation — all in pure F# with System.Security.Cryptography.

No BouncyCastle. No OpenSSL bindings. Just .NET crypto APIs and BigInteger.

Install

dotnet add package TDesu.Telegram.Crypto

Modules

AesIge

AES-256-IGE (Infinite Garble Extension) mode — the non-standard block cipher mode used by MTProto for message encryption.

open TDesu.Crypto

// Encrypt (data length must be multiple of 16)
let encrypted = AesIge.encrypt plaintext key iv

// Decrypt
let decrypted = AesIge.decrypt ciphertext key iv
  • Key: 32 bytes (AES-256)
  • IV: 32 bytes (split into two 16-byte halves internally)
  • Data: must be aligned to 16 bytes (use Padding.addPadding first)
  • Validates input lengths, throws ArgumentException on mismatch

KeyDerivation

MTProto 2.0 key derivation — derives AES key + IV from auth_key and msg_key per the specification.

open TDesu.Crypto

// x = 0 for client->server, x = 8 for server->client
let { Key = aesKey; Iv = aesIv } = KeyDerivation.deriveAesKeyIv authKey msgKey x

Internally computes sha256_a and sha256_b from slices of auth_key and msg_key, then interleaves the hashes to produce a 32-byte key and 32-byte IV.

DiffieHellman

2048-bit Diffie-Hellman key exchange as used in MTProto authorization key creation.

open TDesu.Crypto

// Generate b and g^b mod p (server side)
let (b, gb) = DiffieHellman.generateGB g p

// Compute shared secret from g^a and b
let authKey = DiffieHellman.computeAuthKey ga b p

// Validate DH parameters (security checks per MTProto spec)
let isValid = DiffieHellman.validateDhParams g p gb

Validation includes:

  • 1 < g < p-1 and 1 < g^a < p-1
  • p is a known safe 2048-bit prime
  • g^a is within valid range (not 0, 1, or p-1)

All arithmetic uses System.Numerics.BigInteger with big-endian ↔ little-endian conversion (MTProto uses big-endian, .NET uses little-endian).

Rsa

RSA encryption for the initial DH key exchange. Raw data^e mod n without PKCS padding (MTProto custom format).

open TDesu.Crypto

// Encrypt data with Telegram's production RSA key
let key = Rsa.publicKeys |> List.head
let encrypted = Rsa.encrypt data key    // byte[] -> byte[] (modulus length)

// Register test server keys at runtime
Rsa.addKey testServerKey
let allKeys = Rsa.allKeys ()            // production + registered

// Cleanup
Rsa.clearAdditionalKeys ()

The production RSA key fingerprint is 0xd09d1d85de64fd85 (exponent 65537).

Padding

Random padding for MTProto message encryption. Ensures ciphertext length is a multiple of 16 bytes.

open TDesu.Crypto

// Add 12-1024 bytes of random padding, result aligned to 16
let padded = Padding.addPadding plaintext

// Generate random bytes
let nonce = Padding.randomBytes 16

AuthKeyId

Compute auth_key_id — the 8-byte identifier derived from SHA1 of the authorization key.

open TDesu.Crypto

// auth_key_id = SHA1(auth_key)[12..19] as int64 LE
let keyId = AuthKeyId.compute authKey

// Hash helpers
let sha1Hash = AuthKeyId.sha1 data
let sha256Hash = AuthKeyId.sha256 data

How these fit together

A typical MTProto message encryption flow:

1. Serialize message body        → TDesu.Telegram.Serialization
2. Add random padding            → Padding.addPadding
3. Compute msg_key (SHA-256)     → AuthKeyId.sha256
4. Derive AES key + IV           → KeyDerivation.deriveAesKeyIv
5. Encrypt with AES-IGE          → AesIge.encrypt
6. Prepend auth_key_id + msg_key → AuthKeyId.compute

For the initial DH handshake:

1. Generate nonce                → Padding.randomBytes
2. Encrypt PQ inner data         → Rsa.encrypt
3. Generate DH params            → DiffieHellman.generateGB
4. Derive auth_key               → DiffieHellman.computeAuthKey
5. Compute auth_key_id           → AuthKeyId.compute

Dependencies

  • TDesu.FSharp (>= 1.1.0) — Guard, Bytes.concat, Bytes.xor
  • No other dependencies (uses only System.Security.Cryptography and System.Numerics)

Building

dotnet build
dotnet test

References

License

Unlicense

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on TDesu.Telegram.Crypto:

Package Downloads
TDesu.Telegram.Protocol

MTProto protocol core — encrypted/unencrypted message framing, session state, auth key Diffie–Hellman exchange, RPC dispatcher, and high-level client. Builds on TDesu.Telegram.Transport for TCP and TDesu.Telegram.Crypto for AES/RSA.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.0 372 4/16/2026
0.1.0 112 4/10/2026