#![no_std]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc = include_str!("../README.md")]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg"
)]
#![forbid(unsafe_code)]
#![warn(missing_docs, unused_qualifications)]
use core::fmt;
use kdf::Pbkdf;
pub trait Pake {
type ClientProof: AsRef<[u8]> + for<'a> TryFrom<&'a [u8]>;
type HandshakeState: HandshakeState<
ClientProof = Self::ClientProof,
ServerProof = Self::ServerProof,
SharedSecret = Self::SharedSecret,
>;
type UserVerifier: AsRef<[u8]> + for<'a> TryFrom<&'a [u8]>;
type ServerProof: AsRef<[u8]> + for<'a> TryFrom<&'a [u8]>;
type ServerProofVerifier: ProofVerifier<
Proof = Self::ClientProof,
VerificationProof = Self::ServerProof,
SharedSecret = Self::SharedSecret,
>;
type SharedSecret: AsRef<[u8]> + for<'a> TryFrom<&'a [u8]>;
fn generate_user_verifier<Kdf: Pbkdf>(
&self,
username: &[u8],
password: &[u8],
salt: &[u8],
) -> Result<Self::UserVerifier>;
fn init_handshake(
&self,
username: &[u8],
verifier: &Self::UserVerifier,
) -> (Self::HandshakeState, Self::ServerProofVerifier);
}
pub trait HandshakeState: for<'a> TryFrom<&'a [u8]> {
type ClientProof: AsRef<[u8]> + for<'a> TryFrom<&'a [u8]>;
type ClientProofVerifier: ProofVerifier<
Proof = Self::ServerProof,
VerificationProof = Self::ClientProof,
SharedSecret = Self::SharedSecret,
>;
type SerializedHandshake: AsRef<[u8]> + for<'a> TryFrom<&'a [u8]>;
type ServerProof: AsRef<[u8]> + for<'a> TryFrom<&'a [u8]>;
type SharedSecret: AsRef<[u8]> + for<'a> TryFrom<&'a [u8]>;
fn to_bytes(&self) -> Self::SerializedHandshake;
fn client_proof<Kdf: Pbkdf>(
&self,
username: &[u8],
password: &[u8],
salt: &[u8],
) -> Result<(Self::ClientProof, Self::ClientProofVerifier)>;
}
pub trait ProofVerifier {
type Proof: AsRef<[u8]>;
type VerificationProof: AsRef<[u8]> + for<'a> TryFrom<&'a [u8]>;
type SharedSecret: AsRef<[u8]> + for<'a> TryFrom<&'a [u8]>;
fn verify_proof(
&self,
proof: &Self::Proof,
) -> Result<(Self::VerificationProof, Self::SharedSecret)>;
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Error;
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("PAKE error")
}
}
impl core::error::Error for Error {}
pub type Result<T> = core::result::Result<T, Error>;