Expand description
A Rust implementation of Olm and Megolm
vodozemac is a Rust reimplementation of libolm, a cryptographic library used for end-to-end encryption in Matrix. At its core, it is an implementation of the Olm and Megolm cryptographic ratchets, along with a high-level API to easily establish cryptographic communication channels employing those ratchets with other parties. It also implements some other miscellaneous cryptographic functionality which is useful for building Matrix clients, such as SAS.
§Olm
Olm is an implementation of the Double Ratchet algorithm, very similar to that employed by the Signal Protocol. It allows the establishment of a 1-to-1 private communication channel, with perfect forward secrecy and self-healing properties.
A detailed technical specification can be found at https://gitlab.matrix.org/matrix-org/olm/-/blob/master/docs/olm.md.
For more information on using vodozemac for Olm, see the olm
module.
§Megolm
Megolm is an AES-based single ratchet for group conversations with a large number of participants, where using Olm would be cost prohibitive because it would imply encrypting each message individually for each participant. Megolm sidesteps this by encrypting messages with a symmetric ratchet, shared once with each participant and then reused for a sequence of messages before rotating.
This is a trade-off in which we lose Olm’s self-healing properties, because someone in possession of a Megolm session at a particular state can derive all future states. However, if the attacker is only able to obtain the session in a ratcheted state, they cannot use it to decrypt messages encrypted with an earlier state. This preserves forward secrecy.
A detailed technical specification can be found at https://gitlab.matrix.org/matrix-org/olm/-/blob/master/docs/megolm.md.
For more information on using vodozemac for Megolm, see the megolm
module.
§Features
§Supported
§Unsupported
- Creating asymmetric server-side message key backups, since they are slated to be replaced with symmetric backups.
§Planned
- Symmetric server-side message key backups
- Importing asymmetric server-side message key backups, for compatibility with existing backups created by libolm.
§Feature flags
§Low-level API
Feature: low-level-api
(default: off)
Vodozemac exposes some lower-level structs and functions that are only useful in very advanced use cases. These should not be needed by the vast majority of users.
Extreme care must be taken when using such APIs, as incorrect usage can lead to broken sessions.
§Pickling
vodozemac supports serializing its entire internal state into a form a “pickle”. The state can subsequently be restored from such a pickle (“unpickled”) in order to continue operation. This is used to support some Matrix features like device dehydration.
§Legacy pickles
The legacy pickle format is a simple binary format used by libolm. Implemented for interoperability with current clients which are using libolm. Only unpickling is supported.
§Modern pickles
The crate also implements a modern pickling mechanism using Serde. The exact serialization format is not mandated nor specified by this crate, but you can serialize to and deserialize from any format supported by Serde.
The following structs support pickling:
For example, the following will print out the JSON representing the
serialized Account
and will leave no new copies of the account’s secrets
in memory:
use anyhow::Result;
use vodozemac::olm::{Account, AccountPickle};
const PICKLE_KEY: [u8; 32] = [0u8; 32];
fn main() -> Result<()>{
let mut account = Account::new();
account.generate_one_time_keys(10);
account.generate_fallback_key();
let pickle = account.pickle().encrypt(&PICKLE_KEY);
let account2: Account = AccountPickle::from_encrypted(&pickle, &PICKLE_KEY)?.into();
assert_eq!(account.identity_keys(), account2.identity_keys());
Ok(())
}
You can unpickle a pickle-able struct directly from its serialized form:
let mut json_str = serde_json::to_string(&some_account.pickle())?;
// This will produce an account which is identical to `some_account`.
let account: Account = serde_json::from_str::<AccountPickle>(&json_str)?.into();
json_str.zeroize();
However, the pickle-able structs do not implement serde::Serialize
themselves. If you want to serialize to a format other than JSON, you should
instead call the .pickle()
method to obtain a special serializable struct.
This struct does implement Serialize
and can therefore be serialized
into any format supported by serde
. To get back to the original struct
from such as serializable struct, just call .unpickle()
.
use anyhow::Result;
use vodozemac::olm::Account;
fn main() -> Result<()> {
let account = Account::new();
let account: Account = account.pickle().into(); // this is identity
Ok(())
}
Modules§
- Implementation of an integrated encryption scheme.
- An implementation of the Megolm ratchet.
- An implementation of the Olm double ratchet.
- ☣️ Compat support for libolm’s PkEncryption and PkDecryption
- User-friendly key verification using short authentication strings (SAS).
Structs§
- Struct representing a Curve25519 public key.
- Struct representing a Curve25519 secret key.
- A struct collecting both a public, and a secret, Ed25519 key.
- An Ed25519 public key, used to verify digital signatures.
- An Ed25519 secret key, used to create digital signatures.
- An Ed25519 digital signature, can be used to verify the authenticity of a message.
- A unique identifier for a one-time
Curve25519PublicKey
. - A Protobuf message decoding error.
- The result of a Diffie-Hellman key exchange.
Enums§
- Errors that can occur while decoding.
- Error type describing the different ways message decoding can fail.
- Error type for failures that may occur when decoding or using a cryptographic key.
- Error type describing the various ways libolm pickles can fail to be decoded.
- Error type describing the various ways Vodozemac pickles can fail to be decoded.
- Error type describing signature verification failures.
Statics§
- The version of vodozemac that is being used.
Functions§
- Decode the input as base64 with no padding.
- Encode the input as base64 with no padding.