use core::fmt::{self, Display};
mod private {
pub trait Sealed {}
}
pub trait PaserkVersion: private::Sealed + Default + Clone + Copy + Send + Sync + 'static {
const PREFIX: &'static str;
const VERSION: u8;
}
pub trait UsesBlake2b: PaserkVersion {}
pub trait UsesSha384: PaserkVersion {}
pub trait UsesArgon2: PaserkVersion {}
pub trait UsesPbkdf2: PaserkVersion {}
pub trait UsesX25519: PaserkVersion {}
pub trait UsesP384: PaserkVersion {}
#[deprecated(
since = "0.1.0",
note = "RSA is vulnerable to RUSTSEC-2023-0071 (Marvin Attack). Use K4 with X25519 instead."
)]
pub trait UsesRsa: PaserkVersion {}
pub trait UsesXChaCha20: PaserkVersion {}
pub trait UsesAesCtr: PaserkVersion {}
#[deprecated(
since = "0.1.0",
note = "K1 uses RSA which is vulnerable to RUSTSEC-2023-0071 (Marvin Attack). Use K4 instead."
)]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct K1;
#[allow(deprecated)]
impl private::Sealed for K1 {}
#[allow(deprecated)]
impl PaserkVersion for K1 {
const PREFIX: &'static str = "k1";
const VERSION: u8 = 1;
}
#[allow(deprecated)]
impl UsesSha384 for K1 {}
#[allow(deprecated)]
impl UsesPbkdf2 for K1 {}
#[allow(deprecated)]
impl UsesRsa for K1 {}
#[allow(deprecated)]
impl UsesAesCtr for K1 {}
#[allow(deprecated)]
impl Display for K1 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", Self::PREFIX)
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct K2;
impl private::Sealed for K2 {}
impl PaserkVersion for K2 {
const PREFIX: &'static str = "k2";
const VERSION: u8 = 2;
}
impl UsesBlake2b for K2 {}
impl UsesArgon2 for K2 {}
impl UsesX25519 for K2 {}
impl UsesXChaCha20 for K2 {}
impl Display for K2 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", Self::PREFIX)
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct K3;
impl private::Sealed for K3 {}
impl PaserkVersion for K3 {
const PREFIX: &'static str = "k3";
const VERSION: u8 = 3;
}
impl UsesSha384 for K3 {}
impl UsesPbkdf2 for K3 {}
impl UsesP384 for K3 {}
impl UsesAesCtr for K3 {}
impl Display for K3 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", Self::PREFIX)
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct K4;
impl private::Sealed for K4 {}
impl PaserkVersion for K4 {
const PREFIX: &'static str = "k4";
const VERSION: u8 = 4;
}
impl UsesBlake2b for K4 {}
impl UsesArgon2 for K4 {}
impl UsesX25519 for K4 {}
impl UsesXChaCha20 for K4 {}
impl Display for K4 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", Self::PREFIX)
}
}
#[cfg(test)]
#[allow(deprecated)]
mod tests {
use super::*;
#[test]
fn test_version_prefixes() {
assert_eq!(K1::PREFIX, "k1");
assert_eq!(K2::PREFIX, "k2");
assert_eq!(K3::PREFIX, "k3");
assert_eq!(K4::PREFIX, "k4");
}
#[test]
fn test_version_numbers() {
assert_eq!(K1::VERSION, 1);
assert_eq!(K2::VERSION, 2);
assert_eq!(K3::VERSION, 3);
assert_eq!(K4::VERSION, 4);
}
#[test]
fn test_display() {
assert_eq!(K1.to_string(), "k1");
assert_eq!(K2.to_string(), "k2");
assert_eq!(K3.to_string(), "k3");
assert_eq!(K4.to_string(), "k4");
}
#[test]
fn test_default() {
let k1: K1 = K1;
let k2: K2 = K2;
let k3: K3 = K3;
let k4: K4 = K4;
assert_eq!(k1, K1);
assert_eq!(k2, K2);
assert_eq!(k3, K3);
assert_eq!(k4, K4);
}
#[test]
fn test_copy_clone() {
let k4 = K4;
let k4_clone = k4;
let k4_copy = k4;
assert_eq!(k4_clone, K4);
assert_eq!(k4_copy, K4);
}
}