Expand description
§RustCrypto: SRP
Pure Rust implementation of the Secure Remote Password password-authenticated key-exchange algorithm. Maintained as part of the PAKEs-Conflux workspace.
§About
This implementation is generic over hash functions using the Digest trait,
so you will need to choose a hash function, e.g. Sha256 from sha2 crate.
Additionally this crate allows to use a specialized password hashing algorithm for private key computation instead of method described in the SRP literature.
Compatibility with other implementations has not yet been tested.
§SecretKey usage (session key handling)
SRP verifier types hold the derived session key as secret_utils::wrappers::SecretKey. Where available, prefer using accessor methods that return &SecretKey (e.g., SrpClientVerifier::key_secret()), then borrow bytes with as_ref().
This wrapper:
- Zeroizes its contents on drop (
ZeroizeOnDrop) - Redacts
Debugoutput to avoid accidental leaks - Is not
Clone, reducing accidental copies - Allows borrowing bytes via
as_ref()or deref to&[u8]
Examples:
- Compare two session keys (equality)
use secret_utils::wrappers::SecretKey;
fn equal_keys(k1: &SecretKey, k2: &SecretKey) -> bool {
// Standard equality; do not rely on constant-time properties here.
k1 == k2
}- Hex encode a session key (only when necessary)
use secret_utils::wrappers::SecretKey;
// Requires the `hex` crate when you actually use this pattern.
fn key_as_hex(key: &SecretKey) -> String {
// Borrow without copying the underlying bytes
let bytes: &[u8] = key.as_ref();
hex::encode(bytes)
}
// Even though Debug is redacted, avoid logging secrets altogether.- Drop semantics (automatic zeroization when leaving scope)
use secret_utils::wrappers::SecretKey;
fn ephemeral_use() {
{
// SRP verifier types hold `SecretKey`; constructed here for demo.
let key = SecretKey::from(vec![0u8; 32]);
// use `key.as_ref()` to access bytes
let _first_byte = key.as_ref().get(0).copied();
} // key is zeroized here on drop
}Notes:
- Prefer borrowing (
&[u8]) instead of taking ownership. - Do not print or log keys; use authenticated encryption if you must serialize.
§⚠️ Security Warning
This crate has never received an independent third party audit for security and correctness.
USE AT YOUR OWN RISK!
§Minimum Supported Rust Version
Rust 1.61 or higher.
Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump.
§License
Licensed under either of:
at your option.
§Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
§Usage
Add srp-conflux dependency to your Cargo.toml:
[dependencies]
srp-conflux = "0.6"Next read documentation for client and
server modules.
§Algorithm description
Here we briefly describe implemented algorithm. For additional information
refer to SRP literature. All arithmetic is done modulo N, where N is a
large safe prime (N = 2q+1, where q is prime). Additionally g MUST be
a generator modulo N. It’s STRONGLY recommended to use SRP parameters
provided by this crate in the groups module.
| Client | Data transfer | Server |
|---|---|---|
a_pub = g^a | — a_pub, I —> | (lookup s, v for given I) |
x = PH(P, s) | <— b_pub, s — | b_pub = k*v + g^b |
u = H(a_pub ‖ b_pub) | u = H(a_pub ‖ b_pub) | |
s = (b_pub - k*g^x)^(a+u*x) | S = (b_pub - k*g^x)^(a+u*x) | |
K = H(s) | K = H(s) | |
M1 = H(A ‖ B ‖ K) | — M1 —> | (verify M1) |
(verify M2) | <— M2 — | M2 = H(A ‖ M1 ‖ K) |
Variables and notations have the following meaning:
I— user identity (username)P— user passwordH— one-way hash functionPH— password hashing algroithm, in the RFC 5054 described asH(s ‖ H(I ‖ ":" ‖ P))^— (modular) exponentiation‖— concatenationx— user private keys— salt generated by user and stored on the serverv— password verifier equal tog^xand stored on the servera,b— secret ephemeral values (at least 256 bits in length)A,B— Public ephemeral valuesu— scrambling parameterk— multiplier parameter (k = H(N || g)in SRP-6a)