Skip to main content

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::*;