1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//! # hofmann-rfc
//!
//! Rust implementation of three layered IETF RFCs for password-authenticated
//! key exchange:
//!
//! - **RFC 9380** — Hash-to-Elliptic-Curves (Simplified SWU, `expand_message_xmd`)
//! - **RFC 9497** — Oblivious Pseudorandom Functions (OPRF), base mode
//! - **RFC 9807** — OPAQUE asymmetric PAKE protocol
//!
//! ## Supported Cipher Suites
//!
//! | Suite | Curve | Hash | Element Size | Scalar Size | Hash Output |
//! |---|---|---|---|---|---|
//! | P256-SHA256 | NIST P-256 | SHA-256 | 33 bytes | 32 bytes | 32 bytes |
//! | P384-SHA384 | NIST P-384 | SHA-384 | 49 bytes | 48 bytes | 48 bytes |
//! | P521-SHA512 | NIST P-521 | SHA-512 | 67 bytes | 66 bytes | 64 bytes |
//! | ristretto255-SHA512 | ristretto255 | SHA-512 | 32 bytes | 32 bytes | 64 bytes |
//!
//! ## Quick Start: OPAQUE Registration + Authentication
//!
//! ```rust
//! use hofmann_rfc::opaque::config::OpaqueConfig;
//! use hofmann_rfc::opaque::{OpaqueClient, OpaqueServer};
//!
//! let config = OpaqueConfig::for_testing();
//! let mut rng = rand::thread_rng();
//!
//! // --- Server setup ---
//! let server = OpaqueServer::generate(&config, &mut rng);
//! let client = OpaqueClient::new(&config);
//!
//! // --- Registration ---
//! let reg_state = client.create_registration_request(b"password", &mut rng);
//! let reg_response = server.create_registration_response(®_state.request, b"user@example.com");
//! let record = client.finalize_registration(®_state, ®_response, None, None, &mut rng);
//!
//! // --- Authentication ---
//! let auth_state = client.generate_ke1(b"password", &mut rng);
//! let ke2_result = server.generate_ke2(
//! None, &record, b"user@example.com", &auth_state.ke1, None, &mut rng,
//! );
//! let auth_result = client.generate_ke3(&auth_state, None, None, &ke2_result.ke2).unwrap();
//! let session_key = server.server_finish(&ke2_result.server_auth_state, &auth_result.ke3).unwrap();
//!
//! assert_eq!(auth_result.session_key, session_key);
//! ```
//!
//! ## Module Organization
//!
//! - [`common`] — Byte-level utilities (I2OSP, concat, XOR, constant-time equality)
//! - [`elliptic_curve`] — [`GroupSpec`](elliptic_curve::GroupSpec) trait and curve implementations
//! - [`oprf`] — RFC 9497 OPRF cipher suite ([`OprfCipherSuite`](oprf::OprfCipherSuite))
//! - [`opaque`] — RFC 9807 OPAQUE protocol ([`OpaqueClient`](opaque::OpaqueClient),
//! [`OpaqueServer`](opaque::OpaqueServer))
//!
//! ## Security
//!
//! This library has **not** been formally audited. Use at your own risk in
//! production systems. All MAC comparisons use constant-time equality, and
//! sensitive state (`ClientAuthState`, `ClientRegistrationState`,
//! `ServerAuthState`, `AuthResult`, `RegistrationRecord`) is zeroized on drop.