use super::OpaqueCipherSuite;
pub const NN: usize = 32;
pub struct OpaqueConfig {
cipher_suite: OpaqueCipherSuite,
argon2_memory: u32,
argon2_iterations: u32,
argon2_parallelism: u32,
context: Vec<u8>,
use_argon2: bool,
}
impl OpaqueConfig {
pub fn for_testing() -> Self {
Self {
cipher_suite: OpaqueCipherSuite::p256_sha256(),
argon2_memory: 0,
argon2_iterations: 0,
argon2_parallelism: 0,
context: b"OPAQUE-POC".to_vec(),
use_argon2: false,
}
}
pub fn for_testing_with_suite(suite: OpaqueCipherSuite) -> Self {
Self {
cipher_suite: suite,
argon2_memory: 0,
argon2_iterations: 0,
argon2_parallelism: 0,
context: b"OPAQUE-POC".to_vec(),
use_argon2: false,
}
}
pub fn default_config() -> Self {
Self {
cipher_suite: OpaqueCipherSuite::p256_sha256(),
argon2_memory: 65536,
argon2_iterations: 3,
argon2_parallelism: 1,
context: b"OPAQUE-3DH".to_vec(),
use_argon2: true,
}
}
pub fn with_argon2id(
suite: OpaqueCipherSuite,
context: Vec<u8>,
memory: u32,
iterations: u32,
parallelism: u32,
) -> Self {
Self {
cipher_suite: suite,
argon2_memory: memory,
argon2_iterations: iterations,
argon2_parallelism: parallelism,
context,
use_argon2: true,
}
}
pub fn cipher_suite(&self) -> &OpaqueCipherSuite {
&self.cipher_suite
}
pub fn context(&self) -> &[u8] {
&self.context
}
pub fn nm(&self) -> usize {
self.cipher_suite.nm()
}
pub fn nh(&self) -> usize {
self.cipher_suite.nh()
}
pub fn nx(&self) -> usize {
self.cipher_suite.nx()
}
pub fn npk(&self) -> usize {
self.cipher_suite.npk()
}
pub fn nsk(&self) -> usize {
self.cipher_suite.nsk()
}
pub fn noe(&self) -> usize {
self.cipher_suite.noe()
}
pub fn nok(&self) -> usize {
self.cipher_suite.nok()
}
pub fn envelope_size(&self) -> usize {
self.cipher_suite.envelope_size()
}
pub fn masked_response_size(&self) -> usize {
self.cipher_suite.masked_response_size()
}
pub fn stretch_password(&self, input: &[u8]) -> Vec<u8> {
if self.use_argon2 {
use argon2::Argon2;
let salt = [0u8; NN];
let params = argon2::Params::new(
self.argon2_memory,
self.argon2_iterations,
self.argon2_parallelism,
Some(self.nh()),
)
.expect("invalid Argon2 params");
let argon2 = Argon2::new(argon2::Algorithm::Argon2id, argon2::Version::V0x13, params);
let mut output = vec![0u8; self.nh()];
argon2
.hash_password_into(input, &salt, &mut output)
.expect("Argon2id failed");
output
} else {
input.to_vec()
}
}
pub fn random_bytes(&self, len: usize, rng: &mut dyn rand_core::CryptoRngCore) -> Vec<u8> {
let mut buf = vec![0u8; len];
rng.fill_bytes(&mut buf);
buf
}
}