auths_core/pairing/mod.rs
1//! Pairing protocol for cross-device identity linking.
2//!
3//! This module implements a secure pairing protocol that allows users to link
4//! multiple devices to the same identity. The protocol uses X25519 ECDH key
5//! exchange with Ed25519 signature binding to ensure secure device authentication
6//! and forward secrecy.
7//!
8//! # Protocol Flow
9//!
10//! 1. **Initiating device** generates a `PairingToken` with:
11//! - Controller DID (identity of the initiator)
12//! - X25519 ephemeral public key
13//! - Alphanumeric short code (6-char, no ambiguous chars)
14//! - Capabilities to grant
15//! - 5-minute expiry
16//!
17//! 2. **Initiating device** displays the token as:
18//! - QR code (preferred)
19//! - Alphanumeric short code (fallback)
20//!
21//! 3. **Responding device** scans/enters the token and creates a `PairingResponse`:
22//! - Generates its own X25519 ephemeral key
23//! - Performs ECDH with initiator's key → shared secret
24//! - Signs binding message (short_code || initiator_x25519 || device_x25519)
25//! - Includes its Ed25519 public key and DID
26//!
27//! 4. **Initiating device** verifies the response and completes ECDH:
28//! - Verifies Ed25519 signature binding
29//! - Performs ECDH with responder's X25519 key → same shared secret
30//! - Creates device attestation
31//!
32//! # Example
33//!
34//! ```no_run
35//! use auths_core::pairing::{PairingToken, PairingResponse, format_pairing_qr};
36//! use chrono::{DateTime, Utc};
37//!
38//! // `now` is injected by the caller (e.g., clock.now() at presentation boundary)
39//! fn initiate_pairing(now: DateTime<Utc>) {
40//! let mut session = PairingToken::generate(
41//! now,
42//! "did:keri:controller123".to_string(),
43//! "http://localhost:3000".to_string(),
44//! vec!["sign_commit".to_string()],
45//! ).unwrap();
46//! let display = format_pairing_qr(&session.token).unwrap();
47//! print!("{}", display);
48//!
49//! // Get the URI for QR code
50//! let uri = session.token.to_uri();
51//! }
52//! ```
53
54mod error;
55mod qr;
56mod response;
57mod token;
58pub mod types;
59
60pub use error::PairingError;
61pub use qr::{QrOptions, format_pairing_qr, render_qr, render_qr_from_data};
62pub use response::PairingResponse;
63pub use token::{PairingSession, PairingToken, normalize_short_code};
64pub use types::*;