atagen

matrix-rust-sdk

public
Star0
Watch0
ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk.git

Blame: crates/matrix-sdk-store-encryption/README.md

7ff8adafe9e4atagen2026-10-22 12:30 UTC1
A general purpose encryption scheme for key/value stores.
7ff8adafe9e4atagen2026-10-22 12:30 UTC2
7ff8adafe9e4atagen2026-10-22 12:30 UTC3
# Usage
7ff8adafe9e4atagen2026-10-22 12:30 UTC4
7ff8adafe9e4atagen2026-10-22 12:30 UTC5
```rust
7ff8adafe9e4atagen2026-10-22 12:30 UTC6
use matrix_sdk_store_encryption::StoreCipher;
7ff8adafe9e4atagen2026-10-22 12:30 UTC7
use serde_json::{json, value::Value};
7ff8adafe9e4atagen2026-10-22 12:30 UTC8
7ff8adafe9e4atagen2026-10-22 12:30 UTC9
fn main() -> anyhow::Result<()> {
7ff8adafe9e4atagen2026-10-22 12:30 UTC10
    let store_cipher = StoreCipher::new()?;
7ff8adafe9e4atagen2026-10-22 12:30 UTC11
7ff8adafe9e4atagen2026-10-22 12:30 UTC12
    // Export the store cipher and persist it in your key/value store
7ff8adafe9e4atagen2026-10-22 12:30 UTC13
    let export = store_cipher.export("secret-passphrase")?;
7ff8adafe9e4atagen2026-10-22 12:30 UTC14
7ff8adafe9e4atagen2026-10-22 12:30 UTC15
    let value = json!({
7ff8adafe9e4atagen2026-10-22 12:30 UTC16
        "some": "data",
7ff8adafe9e4atagen2026-10-22 12:30 UTC17
    });
7ff8adafe9e4atagen2026-10-22 12:30 UTC18
7ff8adafe9e4atagen2026-10-22 12:30 UTC19
    let encrypted = store_cipher.encrypt_value(&value)?;
7ff8adafe9e4atagen2026-10-22 12:30 UTC20
    let decrypted: Value = store_cipher.decrypt_value(&encrypted)?;
7ff8adafe9e4atagen2026-10-22 12:30 UTC21
7ff8adafe9e4atagen2026-10-22 12:30 UTC22
    assert_eq!(value, decrypted);
7ff8adafe9e4atagen2026-10-22 12:30 UTC23
7ff8adafe9e4atagen2026-10-22 12:30 UTC24
    let key = "bulbasaur";
7ff8adafe9e4atagen2026-10-22 12:30 UTC25
7ff8adafe9e4atagen2026-10-22 12:30 UTC26
    // Hash the key so people don't know which pokemon we have collected.
7ff8adafe9e4atagen2026-10-22 12:30 UTC27
    let hashed_key = store_cipher.hash_key("list-of-pokemon", key.as_ref());
7ff8adafe9e4atagen2026-10-22 12:30 UTC28
    let another_table = store_cipher.hash_key("my-starter", key.as_ref());
7ff8adafe9e4atagen2026-10-22 12:30 UTC29
    let same_key = store_cipher.hash_key("my-starter", key.as_ref());
7ff8adafe9e4atagen2026-10-22 12:30 UTC30
7ff8adafe9e4atagen2026-10-22 12:30 UTC31
    assert_ne!(key.as_ref(), hashed_key);
7ff8adafe9e4atagen2026-10-22 12:30 UTC32
    assert_ne!(hashed_key, another_table);
7ff8adafe9e4atagen2026-10-22 12:30 UTC33
    assert_eq!(another_table, same_key);
7ff8adafe9e4atagen2026-10-22 12:30 UTC34
7ff8adafe9e4atagen2026-10-22 12:30 UTC35
    Ok(())
7ff8adafe9e4atagen2026-10-22 12:30 UTC36
}
7ff8adafe9e4atagen2026-10-22 12:30 UTC37
```
7ff8adafe9e4atagen2026-10-22 12:30 UTC38
7ff8adafe9e4atagen2026-10-22 12:30 UTC39
## Security warning: hazmat! ⚠️
7ff8adafe9e4atagen2026-10-22 12:30 UTC40
7ff8adafe9e4atagen2026-10-22 12:30 UTC41
This crate only implements the low-level block cipher function, to be used
7ff8adafe9e4atagen2026-10-22 12:30 UTC42
_only_ as a building block for higher-level constructions. It is NOT intended
7ff8adafe9e4atagen2026-10-22 12:30 UTC43
for direct use in applications.
7ff8adafe9e4atagen2026-10-22 12:30 UTC44
7ff8adafe9e4atagen2026-10-22 12:30 UTC45
USE AT YOUR OWN RISK!
7ff8adafe9e4atagen2026-10-22 12:30 UTC46
7ff8adafe9e4atagen2026-10-22 12:30 UTC47
## Encryption scheme
7ff8adafe9e4atagen2026-10-22 12:30 UTC48
7ff8adafe9e4atagen2026-10-22 12:30 UTC49
The central component of the encryption scheme is the `StoreCipher` type, used
7ff8adafe9e4atagen2026-10-22 12:30 UTC50
for both obfuscating keys and encrypting values of the key/value store.
7ff8adafe9e4atagen2026-10-22 12:30 UTC51
A `StoreCipher` object consists of two randomly-generated 32 byte secrets.
7ff8adafe9e4atagen2026-10-22 12:30 UTC52
7ff8adafe9e4atagen2026-10-22 12:30 UTC53
The first secret is used to encrypt values. XChaCha20Poly1305 with a random
7ff8adafe9e4atagen2026-10-22 12:30 UTC54
nonce is used to encrypt each value. The nonce is saved with the ciphertext.
7ff8adafe9e4atagen2026-10-22 12:30 UTC55
7ff8adafe9e4atagen2026-10-22 12:30 UTC56
The second secret is used as a seed to derive table-specific keys, used to key
7ff8adafe9e4atagen2026-10-22 12:30 UTC57
a keyed hash construction, which is in turn used to hash table data. Currently
7ff8adafe9e4atagen2026-10-22 12:30 UTC58
we use blake3 as the keyed hash construction.
7ff8adafe9e4atagen2026-10-22 12:30 UTC59
7ff8adafe9e4atagen2026-10-22 12:30 UTC60
```text
7ff8adafe9e4atagen2026-10-22 12:30 UTC61
                ┌───────────────────────────────────────┐
7ff8adafe9e4atagen2026-10-22 12:30 UTC62
                │             StoreCipher               │
7ff8adafe9e4atagen2026-10-22 12:30 UTC63
                │   Encryption key |    Hash key seed   │
7ff8adafe9e4atagen2026-10-22 12:30 UTC64
                │      [u8; 32]    |       [u8; 32]     │
7ff8adafe9e4atagen2026-10-22 12:30 UTC65
                └───────────────────────────────────────┘
7ff8adafe9e4atagen2026-10-22 12:30 UTC66
```
7ff8adafe9e4atagen2026-10-22 12:30 UTC67
7ff8adafe9e4atagen2026-10-22 12:30 UTC68
The `StoreCipher` has some Matrix-specific assumptions built in, which ensure
7ff8adafe9e4atagen2026-10-22 12:30 UTC69
that the limits of the cryptographic primitives are not exceeded. If this crate
7ff8adafe9e4atagen2026-10-22 12:30 UTC70
is used for non-Matrix data, users need to ensure:
7ff8adafe9e4atagen2026-10-22 12:30 UTC71
7ff8adafe9e4atagen2026-10-22 12:30 UTC72
1. That individual values are chunked, otherwise decryption might be susceptible
7ff8adafe9e4atagen2026-10-22 12:30 UTC73
   to a DOS attack.
7ff8adafe9e4atagen2026-10-22 12:30 UTC74
2. The `StoreCipher` is periodically rotated/rekeyed.
7ff8adafe9e4atagen2026-10-22 12:30 UTC75
7ff8adafe9e4atagen2026-10-22 12:30 UTC76
## WASM support
7ff8adafe9e4atagen2026-10-22 12:30 UTC77
7ff8adafe9e4atagen2026-10-22 12:30 UTC78
This crate relies on the `random` and `getrandom` crates which don't support
7ff8adafe9e4atagen2026-10-22 12:30 UTC79
WASM automatically.
7ff8adafe9e4atagen2026-10-22 12:30 UTC80
7ff8adafe9e4atagen2026-10-22 12:30 UTC81
Either turn the `js` feature on directly on this crate or depend on `getrandom`
7ff8adafe9e4atagen2026-10-22 12:30 UTC82
with the `js` feature turned on. More info can be found in the
7ff8adafe9e4atagen2026-10-22 12:30 UTC83
[`getrandom` docs](https://docs.rs/getrandom/latest/getrandom/index.html#webassembly-support).