VaettirNet.Olm
0.0.6
dotnet add package VaettirNet.Olm --version 0.0.6
NuGet\Install-Package VaettirNet.Olm -Version 0.0.6
<PackageReference Include="VaettirNet.Olm" Version="0.0.6" />
<PackageVersion Include="VaettirNet.Olm" Version="0.0.6" />
<PackageReference Include="VaettirNet.Olm" />
paket add VaettirNet.Olm --version 0.0.6
#r "nuget: VaettirNet.Olm, 0.0.6"
#:package VaettirNet.Olm@0.0.6
#addin nuget:?package=VaettirNet.Olm&version=0.0.6
#tool nuget:?package=VaettirNet.Olm&version=0.0.6
VaettirNet.Olm
A .NET implementation of the Olm cryptographic ratchet protocol. Olm is an implementation of the Double Ratchet Algorithm, providing strong end-to-end encryption for messaging applications with forward secrecy and break-in recovery properties.
Features
- Complete implementation of the Olm cryptographic ratchet protocol
- X3DH (Extended Triple Diffie-Hellman) key agreement protocol for initial key exchange
- Double Ratchet Algorithm providing strong forward secrecy and post-compromise security
- Support for out-of-order message delivery
- Prevention of replay attacks
- Modern C# 13 implementation targeting .NET 9.0
- Built on BouncyCastle for cryptographic primitives
Installation
Install the package via NuGet:
dotnet add package VaettirNet.Olm
Or via the Package Manager Console:
Install-Package VaettirNet.Olm
The package is automatically versioned using GitVersion and follows semantic versioning. You can check the latest version on NuGet.
Usage
Key Generation
Generating the necessary keys for encryption:
// Generate identity keys (long-term keys)
var aliceIdentity = X3DHPrivateIdentityKey.Generate();
var bobIdentity = X3DHPrivateIdentityKey.Generate();
// Generate ephemeral key for Alice
var aliceEphemeral = X3DHPrivateEphemeralKey.Generate();
// Generate pre-key for Bob
var bobPreKey = X3DHPrivatePreKey.Generate();
Establishing a Session
Alice initiates a session with Bob:
// Alice initiates a session with Bob
var aliceSession = OlmSession.Initiate(
aliceIdentity, // Alice's identity key
bobIdentity.GetPublic(), // Bob's public identity key
aliceEphemeral, // Alice's ephemeral key
bobPreKey.GetPublic() // Bob's public pre-key
);
// Alice sends a first message
var firstMessage = new PlainText("Hello Bob!"u8.ToArray());
var encryptedMessage = aliceSession.CreateOutputMessage(firstMessage);
// encryptedMessage will be an OlmPreKeyMessage for the first message
Bob receives and accepts the session:
// Bob receives the OlmPreKeyMessage and accepts the session
if (OlmSession.TryAcceptNewInbound(
bobIdentity, // Bob's identity key
bobPreKey, // Bob's pre-key
encryptedMessage, // The OlmPreKeyMessage from Alice
out var bobSession, // The newly created session
out var decryptedMessage // The decrypted message
))
{
// Session established successfully
// decryptedMessage contains "Hello Bob!"
Console.WriteLine(Encoding.UTF8.GetString(decryptedMessage.Data.Span));
}
Sending and Receiving Messages
Once a session is established, messages can be exchanged:
// Bob sends a reply
var bobReply = new PlainText("Hi Alice!"u8.ToArray());
var encryptedReply = bobSession.CreateOutputMessage(bobReply);
// Alice receives and decrypts Bob's message
if (aliceSession.TryReceive(encryptedReply, out var decryptedReply))
{
Console.WriteLine(Encoding.UTF8.GetString(decryptedReply.Data.Span)); // "Hi Alice!"
}
Handling Out-of-Order Messages
The library supports out-of-order message delivery:
// Alice sends multiple messages
var message1 = aliceSession.CreateOutputMessage(new PlainText("Message 1"u8.ToArray()));
var message2 = aliceSession.CreateOutputMessage(new PlainText("Message 2"u8.ToArray()));
var message3 = aliceSession.CreateOutputMessage(new PlainText("Message 3"u8.ToArray()));
// Bob can receive them in any order
bobSession.TryReceive(message3, out var decrypted3);
bobSession.TryReceive(message1, out var decrypted1);
bobSession.TryReceive(message2, out var decrypted2);
// All messages will be decrypted correctly
Shared Secret Derivation
For more advanced use cases, you can work directly with the X3DH shared secret:
// Create a shared secret using the X3DH protocol
X3DHSharedSecret aliceSecret = new();
aliceSecret.DeriveInitial(
aliceIdentity, // Alice's identity key
bobIdentity.GetPublic(), // Bob's public identity key
aliceEphemeral, // Alice's ephemeral key
bobPreKey.GetPublic() // Bob's public pre-key
);
// Bob computes the same shared secret
X3DHSharedSecret bobSecret = new();
bobSecret.DeriveResponse(
bobIdentity, // Bob's identity key
aliceIdentity.GetPublic(), // Alice's public identity key
aliceEphemeral.GetPublic(), // Alice's public ephemeral key
bobPreKey // Bob's pre-key
);
// Both shared secrets should be identical
Architecture
VaettirNet.Olm implements the Olm protocol with a focus on security and performance:
- X3DH Key Exchange: Secure initial key agreement protocol using multiple Diffie-Hellman operations to establish a shared secret.
- Double Ratchet Algorithm: Combines a Diffie-Hellman key exchange with a KDF ratchet to provide forward secrecy and break-in recovery.
- Message Keys: One-time keys are derived for each message to ensure messages remain secure even if session keys are compromised.
Security Considerations
- Forward Secrecy: If keys are compromised, previously sent messages remain secure.
- Break-in Recovery: The protocol can recover security if keys are compromised.
- Key Rotation: Regularly rotate pre-keys and ephemeral keys for maximum security.
- Replay Protection: Built-in protection against message replay attacks.
- Side-Channel Mitigation: Uses constant-time operations for cryptographic comparisons to prevent timing attacks.
Requirements
- .NET 9.0
- Dependencies:
- BouncyCastle.Cryptography
- System.Runtime.Caching
Advanced Usage
Session Management
In a real-world application, you'll need to manage multiple sessions:
// Create a session store (you would implement ISessionStore)
private Dictionary<string, OlmSession> _sessions = new();
// Store a session by recipient ID
public void StoreSession(string recipientId, OlmSession session)
{
_sessions[recipientId] = session;
}
// Retrieve a session
public OlmSession GetSession(string recipientId)
{
return _sessions.TryGetValue(recipientId, out var session) ? session : null;
}
Handling Large Messages
The library can handle messages of arbitrary size:
// For large messages, you might want to use streams
public byte[] EncryptLargeFile(OlmSession session, byte[] fileData)
{
var plainText = new PlainText(fileData);
var encrypted = session.CreateOutputMessage(plainText);
// Serialize the encrypted message
var buffer = new byte[1024 * 1024]; // Adjust size as needed
encrypted.TryWrite(buffer, out var bytesWritten);
return buffer[..bytesWritten];
}
Integration with Matrix Protocol
This library can be used as part of a Matrix client implementation for end-to-end encryption:
// Example of integrating with Matrix protocol
public async Task SendEncryptedMatrixMessage(string roomId, string recipientUserId, string messageText)
{
// Get or create session for recipient
var session = GetSessionForUser(recipientUserId);
// Encrypt the message content
var plainText = new PlainText(Encoding.UTF8.GetBytes(messageText));
var encrypted = session.CreateOutputMessage(plainText);
// Serialize to bytes for transmission
var buffer = new byte[8192];
encrypted.TryWrite(buffer, out var bytesWritten);
// Convert to Base64 for JSON transmission
var base64Payload = Convert.ToBase64String(buffer[..bytesWritten]);
// Send via Matrix API (implementation depends on your Matrix client)
await matrixClient.SendEncryptedEvent(roomId, "m.room.encrypted", new {
algorithm = "m.olm.v1.curve25519-aes-sha2",
sender_key = myIdentityKey.GetPublic().ToString(),
ciphertext = new Dictionary<string, object> {
{ recipientCurve25519Identity, new {
body = base64Payload,
type = encrypted is OlmPreKeyMessage ? 0 : 1
}}
}
});
}
Build and Development
- Clone the repository:
git clone https://github.com/ChadNedzlek/Olm.Net.git
- Restore dependencies:
dotnet restore
- Build the project:
dotnet build -c Release
- Run tests:
dotnet test --no-build --verbosity normal --configuration Release
- Run benchmarks:
dotnet run -c Release --project Olm.Benchmarks
Versioning
This project uses GitVersion for semantic versioning. The version is automatically determined based on Git history and tags.
Implementation Details
VaettirNet.Olm is a complete implementation of the Olm protocol specification with these key components:
- X3DHPrivateKey/X3DHPublicKey: Base classes for all key types, handling secure key operations
- X3DHSharedSecret: Handles the derivation of shared secrets using the X3DH protocol
- OlmSession: Manages an encryption session between two parties
- OlmRatchet: Implements the Double Ratchet Algorithm for message encryption/decryption
- OlmMessage/OlmPreKeyMessage: Represents encrypted messages with proper serialization
The implementation uses modern C# 13 features including ref structs for efficient memory usage, native inline arrays for storage optimization, and pattern matching for robust message parsing.
Relationship to Matrix
This library can be used as the core encryption component for Matrix clients. The Olm protocol is used in Matrix for end-to-end encrypted direct messages, while its extension, Megolm, is used for group communications.
License
This project is licensed under the MIT License - see the license information in the package metadata for details.
Author
Chad Nedzlek
Repository
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. 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. |
-
net9.0
- BouncyCastle.Cryptography (>= 2.5.1)
- System.Runtime.Caching (>= 9.0.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
0.0.6 | 480 | 7/22/2025 |