cryptimitives 0.20.0

Cryptographic primitives collection.
Documentation
//! Utility functions and test stubs.

use std::fmt::Display;

use cryptraits::{
    convert::{FromBytes, Len, ToVec},
    kdf::Kdf,
    key::{Generate, PublicKey, SecretKey},
    signature::Signature,
};
use rand_core::{CryptoRng, RngCore};
use zeroize::Zeroize;

use crate::errors::KeyPairError;

#[derive(Debug, PartialEq, Clone, Copy, Eq, Hash, Zeroize)]
pub struct TestPublicKey([u8; 5]);

impl PublicKey for TestPublicKey {
    fn as_bytes(&self) -> &[u8] {
        &self.0
    }
}

impl Display for TestPublicKey {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(&hex::encode(self.to_vec()))
    }
}

impl FromBytes for TestPublicKey {
    type E = KeyPairError;

    fn from_bytes(bytes: &[u8]) -> Result<Self, KeyPairError>
    where
        Self: Sized,
    {
        let mut key: [u8; <Self as Len>::LEN] = [0; <Self as Len>::LEN];

        key[..<Self as Len>::LEN].copy_from_slice(&bytes[..<Self as Len>::LEN]);

        Ok(Self(key))
    }
}

impl Len for TestPublicKey {
    const LEN: usize = 5;
}

impl ToVec for TestPublicKey {
    fn to_vec(&self) -> Vec<u8>
    where
        Self: Sized,
    {
        Vec::from(self.0)
    }
}

#[derive(Debug, Clone, Zeroize)]
#[zeroize(drop)]
pub struct TestSecretKey([u8; 5]);

impl SecretKey for TestSecretKey {
    type PK = TestPublicKey;

    fn to_public(&self) -> Self::PK {
        todo!()
    }
}

impl Generate for TestSecretKey {
    fn generate_with<R: CryptoRng + RngCore>(_csprng: R) -> Self
    where
        Self: Sized,
    {
        todo!()
    }

    fn generate() -> Self {
        todo!()
    }
}

impl FromBytes for TestSecretKey {
    type E = KeyPairError;

    fn from_bytes(bytes: &[u8]) -> Result<Self, KeyPairError>
    where
        Self: Sized,
    {
        let mut key: [u8; Self::LEN] = [0; Self::LEN];

        key[..Self::LEN].copy_from_slice(&bytes[..Self::LEN]);

        Ok(Self(key))
    }
}

impl Len for TestSecretKey {
    const LEN: usize = 5;
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct TestSignature([u8; 2]);

impl Signature for TestSignature {}

impl ToVec for TestSignature {
    fn to_vec(&self) -> Vec<u8>
    where
        Self: Sized,
    {
        Vec::from(self.0)
    }
}

impl Len for TestSignature {
    const LEN: usize = 2;
}

impl FromBytes for TestSignature {
    type E = KeyPairError;

    fn from_bytes(bytes: &[u8]) -> Result<Self, KeyPairError>
    where
        Self: Sized,
    {
        let mut signature: [u8; 2] = [0; 2];

        signature[..2].copy_from_slice(&bytes[..2]);

        Ok(Self(signature))
    }
}

pub fn seed_from_entropy(entropy: &[u8], password: &str) -> Result<[u8; 64], KeyPairError> {
    if entropy.len() < 16 || entropy.len() > 32 || entropy.len() % 4 != 0 {
        return Err(KeyPairError::InvalidEntropy);
    }

    let mut salt = String::with_capacity(8 + password.len());
    salt.push_str("mnemonic");
    salt.push_str(password);

    let mut seed = [0u8; 64];

    let pbkdf2 =
        crate::kdf::pbkdf2::Kdf::<crate::hmac::sha512::Hmac>::new(Some(salt.as_bytes()), entropy);

    pbkdf2
        .pbkdf2(&mut seed, 2048)
        .or(Err(KeyPairError::InvalidEntropy))?;

    salt.zeroize();

    Ok(seed)
}