tauri_plugin_matrix_svelte/stronghold/
utils.rs1use std::path::Path;
2
3use blake2::{Blake2b512, Digest};
4use rand_chacha::ChaCha20Rng;
5use rand_core::{RngCore, SeedableRng};
6use serde::Deserialize;
7
8#[derive(Deserialize, Hash, Eq, PartialEq, Ord, PartialOrd, Clone)]
9#[serde(untagged)]
10pub enum BytesDto {
11 Text(String),
12 Raw(Vec<u8>),
13}
14
15impl AsRef<[u8]> for BytesDto {
16 fn as_ref(&self) -> &[u8] {
17 match self {
18 Self::Text(t) => t.as_ref(),
19 Self::Raw(b) => b.as_ref(),
20 }
21 }
22}
23
24impl From<BytesDto> for Vec<u8> {
25 fn from(v: BytesDto) -> Self {
26 match v {
27 BytesDto::Text(t) => t.as_bytes().to_vec(),
28 BytesDto::Raw(b) => b,
29 }
30 }
31}
32
33const HASH_LENGTH: usize = 32;
34
35pub struct KeyDerivation {}
36
37impl KeyDerivation {
38 pub fn argon2(password: &str, salt_path: &Path) -> Vec<u8> {
42 let mut salt = [0u8; HASH_LENGTH];
43 create_or_get_salt(&mut salt, salt_path);
44
45 argon2::hash_raw(password.as_bytes(), &salt, &Default::default())
46 .expect("Failed to generate hash for password")
47 }
48 pub fn blake2(password: &str, salt_path: &Path) -> Vec<u8> {
49 let mut salt = [0u8; HASH_LENGTH];
50 create_or_get_salt(&mut salt, salt_path);
51
52 let mut hasher = Blake2b512::new();
53 hasher.update(salt);
54 hasher.update(password);
55 hasher.finalize().to_vec()[..32].to_vec()
56 }
57}
58
59fn create_or_get_salt(salt: &mut [u8], salt_path: &Path) {
60 if salt_path.is_file() {
61 let tmp = std::fs::read(salt_path).unwrap();
63 salt.clone_from_slice(&tmp);
64 } else {
65 let mut gen = ChaCha20Rng::from_entropy();
67 gen.fill_bytes(salt);
68 std::fs::write(salt_path, salt).expect("Failed to write salt for Stronghold")
69 }
70}