Crypto Readme
This commit is contained in:
parent
5bfcccc056
commit
30f2a82145
1 changed files with 62 additions and 11 deletions
|
|
@ -4,11 +4,14 @@ Cryptographic primitives for the MTP protocol. Classical and post-quantum.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
| Feature | Primitives | Status |
|
| Feature | Primitives |
|
||||||
|---------|-----------|--------|
|
|---------|-----------|
|
||||||
| `default` | XChaCha20-Poly1305, Ed25519, HKDF-SHA-256, SHA-256 | Classical |
|
| `default` | XChaCha20-Poly1305, Ed25519, ML-DSA-65, HKDF-SHA-256, SHA-256 |
|
||||||
| `full` | default + AES-256-GCM | Classical |
|
| `full` | default + AES-256-GCM |
|
||||||
| `pqc` | ML-KEM-768+X25519 hybrid KEM, ML-DSA-65 | Post-quantum |
|
| `pqc` | ML-KEM-768+X25519 hybrid KEM |
|
||||||
|
|
||||||
|
ML-DSA-65 is enabled by default so dual-signature support is always available
|
||||||
|
without a separate PQC feature flag in protocol crates.
|
||||||
|
|
||||||
## AEAD
|
## AEAD
|
||||||
|
|
||||||
|
|
@ -71,21 +74,65 @@ let ss = HybridKem::decapsulate(&sk, &enc.ciphertext)?;
|
||||||
assert_eq!(enc.shared_secret, ss);
|
assert_eq!(enc.shared_secret, ss);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Encrypted containers
|
||||||
|
|
||||||
|
Self-describing encrypted blobs with algorithm selection via `EncryptionType`.
|
||||||
|
Each blob begins with a marking byte so recipients can decrypt without
|
||||||
|
out-of-band agreement.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use mtp_crypto::{EncryptionType, Keyring, encrypt_for, decrypt_with};
|
||||||
|
|
||||||
|
let kr = Keyring::generate();
|
||||||
|
let blob = encrypt_for(EncryptionType::MlKemChaCha20Poly1305, &kr.public_key_bundle(), b"data", b"aad")?;
|
||||||
|
let pt = decrypt_with(&blob, &kr, b"aad")?;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Multi-recipient encryption
|
||||||
|
|
||||||
|
Encrypt a payload for multiple recipients using a content-encryption key wrapped
|
||||||
|
per-recipient via Hybrid KEM.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use mtp_crypto::{Keyring, encrypt_multi, decrypt_multi};
|
||||||
|
|
||||||
|
let alice = Keyring::generate();
|
||||||
|
let bob = Keyring::generate();
|
||||||
|
let msg = encrypt_multi(b"secret", b"aad", &[alice.public_key_bundle(), bob.public_key_bundle()])?;
|
||||||
|
let pt = decrypt_multi(&msg, b"aad", &alice)?;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Authentication handshake
|
||||||
|
|
||||||
|
Canonical domain-separated payloads for the challenge-response handshake.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use mtp_crypto::auth::{challenge_payload, login_proof_payload, register_proof_payload, host_final_payload};
|
||||||
|
```
|
||||||
|
|
||||||
|
Each payload type uses a distinct domain tag to prevent replay across protocol steps.
|
||||||
|
|
||||||
## KDF
|
## KDF
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use mtp_crypto::{hkdf_expand, derive_encryption_key};
|
use mtp_crypto::{hkdf_expand, hkdf_extract, derive_encryption_key};
|
||||||
|
|
||||||
let key = derive_encryption_key(b"ikm", b"salt", b"context")?;
|
let key = derive_encryption_key(b"ikm", b"salt", b"context")?;
|
||||||
|
let prk = hkdf_extract(b"ikm", b"salt");
|
||||||
```
|
```
|
||||||
|
|
||||||
## Hashing
|
## Hashing
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use mtp_crypto::{sha256, sha256_double};
|
use mtp_crypto::{sha256, sha256_double, Sha256Hasher};
|
||||||
|
|
||||||
let h = sha256(b"data");
|
let h = sha256(b"data");
|
||||||
let h2 = sha256_double(b"data");
|
let h2 = sha256_double(b"data");
|
||||||
|
|
||||||
|
let mut hasher = Sha256Hasher::new();
|
||||||
|
hasher.update(b"da");
|
||||||
|
hasher.update(b"ta");
|
||||||
|
let h3 = hasher.finalize();
|
||||||
```
|
```
|
||||||
|
|
||||||
## Key types
|
## Key types
|
||||||
|
|
@ -101,13 +148,17 @@ let h2 = sha256_double(b"data");
|
||||||
| `SignaturePqPrivateKey` | PQC signing key | Yes |
|
| `SignaturePqPrivateKey` | PQC signing key | Yes |
|
||||||
| `SignaturePqPublicKey` | PQC verifying key | No |
|
| `SignaturePqPublicKey` | PQC verifying key | No |
|
||||||
|
|
||||||
`KeyGroup` holds classical keys; `Keyring` holds all six (hybrid KEM + PQ sig + classical sig).
|
`Keyring` holds all six keys (hybrid KEM + PQ sig + classical sig) plus
|
||||||
|
`generate()`, `to_bytes()`, and `from_bytes()` for serialization.
|
||||||
|
`PublicKeyBundle` holds the three public keys for distribution.
|
||||||
|
|
||||||
## Feature flags
|
## Feature flags
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
mtp-crypto = { path = "../crypto" } # classical
|
mtp-crypto = { path = "../crypto" } # classical + ML-DSA
|
||||||
mtp-crypto = { path = "../crypto", features = ["pqc"] } # post-quantum
|
mtp-crypto = { path = "../crypto", features = ["pqc"] } # adds hybrid KEM
|
||||||
mtp-crypto = { path = "../crypto", features = ["full", "pqc"] } # all
|
mtp-crypto = { path = "../crypto", features = ["full", "pqc"] } # adds AES-256-GCM + hybrid KEM
|
||||||
|
mtp-crypto = { path = "../crypto", features = ["serde"] } # serde support
|
||||||
|
mtp-crypto = { path = "../crypto", features = ["wasm"] } # WASM compat
|
||||||
```
|
```
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue