Skip to content

Commit 2438fcb

Browse files
committed
feat: Add examples and an easy API, refactor documentation structure, and update core message protocol.
1 parent d36ee79 commit 2438fcb

14 files changed

Lines changed: 1580 additions & 11 deletions

IMPLEMENT.md

Lines changed: 636 additions & 0 deletions
Large diffs are not rendered by default.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

lmp-core/examples/basic_usage.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//! Basic LMP Usage Example
2+
//!
3+
//! This example demonstrates how to:
4+
//! 1. Create an LMP client
5+
//! 2. Generate an introduction token
6+
//! 3. Establish a session between two parties
7+
//!
8+
//! Run with: cargo run --example basic_usage
9+
10+
use lmp_core::prelude::*;
11+
12+
fn main() -> Result<()> {
13+
println!("=== LMP Basic Usage Example ===\n");
14+
15+
// Step 1: Create two clients (Alice and Bob)
16+
println!("Creating clients...");
17+
let alice = LmpClient::new()?;
18+
let bob = LmpClient::new()?;
19+
20+
println!(" Alice's device ID: {}", hex::encode(alice.device_id()));
21+
println!(" Bob's device ID: {}", hex::encode(bob.device_id()));
22+
println!();
23+
24+
// Step 2: Get fingerprints for verification
25+
println!("Identity fingerprints (for out-of-band verification):");
26+
println!(" Alice: {}", alice.fingerprint());
27+
println!(" Bob: {}", bob.fingerprint());
28+
println!();
29+
30+
// Step 3: Create introduction tokens
31+
println!("Creating introduction tokens...");
32+
let alice_token = alice.get_introduction_token("dht://alice.example.com:4001")?;
33+
let bob_token = bob.get_introduction_token("dht://bob.example.com:4001")?;
34+
35+
// Verify tokens
36+
alice_token.verify()?;
37+
bob_token.verify()?;
38+
println!(" ✓ Both tokens verified");
39+
println!();
40+
41+
// Step 4: Serialize tokens for sharing
42+
println!("Token sharing (base64 format):");
43+
let alice_b64 = alice_token.to_base64()?;
44+
let bob_b64 = bob_token.to_base64()?;
45+
46+
println!(" Alice's token: {}...{}", &alice_b64[..20], &alice_b64[alice_b64.len()-10..]);
47+
println!(" Bob's token: {}...{}", &bob_b64[..20], &bob_b64[bob_b64.len()-10..]);
48+
println!();
49+
50+
// Step 5: Show token fingerprints for quick verification
51+
println!("Token fingerprints:");
52+
println!(" Alice: {}", alice_token.fingerprint());
53+
println!(" Bob: {}", bob_token.fingerprint());
54+
println!();
55+
56+
// Step 6: Show token validity
57+
println!("Token validity:");
58+
println!(" Alice's token expires in {} days", alice_token.remaining_validity() / 86400);
59+
println!(" Bob's token expires in {} days", bob_token.remaining_validity() / 86400);
60+
println!();
61+
62+
println!("=== Success! ===\n");
63+
println!("Next steps:");
64+
println!(" 1. Share these tokens out-of-band (QR code, secure chat, etc.)");
65+
println!(" 2. Verify fingerprints match in person or via call");
66+
println!(" 3. Use the handshake protocol to establish encrypted sessions");
67+
println!(" 4. See 'handshake_example' for the full flow");
68+
69+
Ok(())
70+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
//! Crypto Primitives Example
2+
//!
3+
//! This example demonstrates direct usage of the cryptographic primitives:
4+
//! - X25519 key exchange
5+
//! - Kyber768 post-quantum KEM
6+
//! - Ed25519 signatures
7+
//! - Dilithium3 post-quantum signatures
8+
//! - ChaCha20-Poly1305 AEAD
9+
//!
10+
//! Run with: cargo run --example crypto_primitives
11+
12+
use lmp_core::crypto::{aead, dilithium, ed25519, hkdf, kyber, x25519};
13+
use lmp_core::error::Result;
14+
15+
fn main() -> Result<()> {
16+
println!("=== LMP Cryptographic Primitives Demo ===\n");
17+
18+
// X25519 Key Exchange
19+
println!("1. X25519 Elliptic Curve Diffie-Hellman");
20+
println!(" ────────────────────────────────────");
21+
let (alice_x25519_pub, alice_x25519_sec) = x25519::generate_keypair()?;
22+
let (bob_x25519_pub, bob_x25519_sec) = x25519::generate_keypair()?;
23+
24+
let alice_shared = x25519::diffie_hellman(&alice_x25519_sec, &bob_x25519_pub)?;
25+
let bob_shared = x25519::diffie_hellman(&bob_x25519_sec, &alice_x25519_pub)?;
26+
27+
println!(" Alice's public key: {}...", hex::encode(&alice_x25519_pub[..8]));
28+
println!(" Bob's public key: {}...", hex::encode(&bob_x25519_pub[..8]));
29+
println!(" Shared secret: {}...", hex::encode(&alice_shared[..8]));
30+
println!(" Secrets match: {}", alice_shared == bob_shared);
31+
println!();
32+
33+
// Kyber768 Post-Quantum KEM
34+
println!("2. Kyber768 Post-Quantum Key Encapsulation");
35+
println!(" ────────────────────────────────────────");
36+
let (kyber_pk, kyber_sk) = kyber::generate_keypair()?;
37+
38+
let (ciphertext, shared_sender) = kyber::encapsulate(&kyber_pk)?;
39+
let shared_receiver = kyber::decapsulate(&ciphertext, &kyber_sk)?;
40+
41+
println!(" Public key size: {} bytes", kyber_pk.len());
42+
println!(" Secret key size: {} bytes", kyber_sk.len());
43+
println!(" Ciphertext size: {} bytes", ciphertext.len());
44+
println!(" Shared secret: {}...", hex::encode(&shared_sender[..8]));
45+
println!(" Secrets match: {}", shared_sender == shared_receiver);
46+
println!();
47+
48+
// Ed25519 Signatures
49+
println!("3. Ed25519 Digital Signatures");
50+
println!(" ──────────────────────────");
51+
let (ed_pub, ed_sec) = ed25519::generate_keypair()?;
52+
let message = b"This is a test message for signing";
53+
54+
let signature = ed25519::sign(message, &ed_sec, &ed_pub)?;
55+
let verify_result = ed25519::verify(message, &signature, &ed_pub);
56+
57+
println!(" Message: \"{}\"", String::from_utf8_lossy(message));
58+
println!(" Signature size: {} bytes", signature.len());
59+
println!(" Signature valid: {}", verify_result.is_ok());
60+
println!();
61+
62+
// Dilithium3 Post-Quantum Signatures
63+
println!("4. Dilithium3 Post-Quantum Signatures");
64+
println!(" ───────────────────────────────────");
65+
let (dil_pk, dil_sk) = dilithium::generate_keypair()?;
66+
67+
let dil_sig = dilithium::sign(message, &dil_sk)?;
68+
let dil_verify = dilithium::verify(message, &dil_sig, &dil_pk);
69+
70+
println!(" Public key size: {} bytes", dil_pk.len());
71+
println!(" Secret key size: {} bytes", dil_sk.len());
72+
println!(" Signature size: {} bytes", dil_sig.len());
73+
println!(" Signature valid: {}", dil_verify.is_ok());
74+
println!();
75+
76+
// ChaCha20-Poly1305 AEAD
77+
println!("5. ChaCha20-Poly1305 Authenticated Encryption");
78+
println!(" ──────────────────────────────────────────");
79+
let mut rng = lmp_core::crypto::rng::SecureRng::new();
80+
let mut key = [0u8; 32];
81+
rng.fill_bytes(&mut key)?;
82+
83+
let aead_cipher = aead::Aead::new(key);
84+
let nonce = [0u8; 12];
85+
let aad = b"additional data";
86+
let plaintext = b"Secret message to encrypt!";
87+
88+
let ciphertext = aead_cipher.encrypt(&nonce, plaintext, aad)?;
89+
let decrypted = aead_cipher.decrypt(&nonce, &ciphertext, aad)?;
90+
91+
println!(" Key: {}...", hex::encode(&key[..8]));
92+
println!(" Plaintext: \"{}\"", String::from_utf8_lossy(plaintext));
93+
println!(" Ciphertext size: {} bytes (includes 16-byte auth tag)", ciphertext.len());
94+
println!(" Decrypted: \"{}\"", String::from_utf8_lossy(&decrypted));
95+
println!(" Decryption OK: {}", plaintext == decrypted.as_slice());
96+
println!();
97+
98+
// HKDF Key Derivation
99+
println!("6. HKDF-SHA3-256 Key Derivation");
100+
println!(" ────────────────────────────");
101+
let salt = b"example salt";
102+
let ikm = b"input key material";
103+
let info = b"application context";
104+
105+
let derived = hkdf::Hkdf::derive_key(salt, ikm, info)?;
106+
107+
println!(" Input key material: \"{}\"", String::from_utf8_lossy(ikm));
108+
println!(" Salt: \"{}\"", String::from_utf8_lossy(salt));
109+
println!(" Info: \"{}\"", String::from_utf8_lossy(info));
110+
println!(" Derived key: {}...", hex::encode(&derived[..16]));
111+
println!();
112+
113+
println!("=== All primitives working correctly! ===");
114+
115+
Ok(())
116+
}

0 commit comments

Comments
 (0)