use opaque_ke::{Ristretto255, TripleDh, ServerSetup, CredentialResponse, RegistrationUploadLen, RegistrationResponse}; use opaque_ke::keypair::{OprfSeed, PrivateKey}; use sha2::Sha512; use opaque_ke::CipherSuite; use opaque_ke::argon2::Argon2; use opaque_ke::generic_array::GenericArray; use uuid::Uuid; use nkode_rs::nkode_core::chacha20prng::SecretKey; use zeroize::Zeroizing; use nkode_rs::from_bytes::FromBytes; use rand::RngCore; use rand::rngs::OsRng; const USER_KEY_SIZE: usize = 16; #[derive(Clone, Eq, PartialEq)] pub struct UserSecretKey(Zeroizing<[u8; USER_KEY_SIZE]>); impl UserSecretKey { pub fn new() -> Self { let mut rng = OsRng; let mut secret_key = [0u8; USER_KEY_SIZE]; rng.fill_bytes(&mut secret_key); Self(Zeroizing::new(secret_key)) } pub fn chacha20_secret_key(&self) -> SecretKey { let out = blake3::derive_key("your-app chacha20 secret key v1", &self.0.as_slice()); SecretKey::from_bytes(&out).unwrap() } pub fn as_slice(&self) -> &[u8] { self.0.as_slice() } } impl FromBytes for UserSecretKey { fn from_array(arr: [u8; USER_KEY_SIZE]) -> Self { Self(Zeroizing::new(arr)) } } const OPAQUE_SESSION_KEY_SIZE: usize = 64; #[derive(Debug, Clone)] pub struct OpaqueSessionKey(Zeroizing<[u8; OPAQUE_SESSION_KEY_SIZE]>); impl FromBytes for OpaqueSessionKey { fn from_array(arr: [u8; OPAQUE_SESSION_KEY_SIZE]) -> Self { Self(Zeroizing::new(arr)) } } impl OpaqueSessionKey { pub fn as_bytes(&self) -> &[u8] { self.0.as_slice() } } pub struct NKodeCipherSuite; impl CipherSuite for NKodeCipherSuite { type OprfCs = Ristretto255; type KeyExchange = TripleDh; type Ksf = Argon2<'static>; } pub type NKodeServerSetup = ServerSetup, OprfSeed>; pub type PasswordFile = GenericArray>; #[derive(Debug, Clone, PartialEq, Eq)] pub struct OpaqueLoginSession { pub response: CredentialResponse, pub session_id: Uuid } #[derive(Debug, Clone, PartialEq, Eq)] pub struct OpaqueRegisterSession { pub response: RegistrationResponse, pub session_id: Uuid }