mirror of
https://github.com/aljazceru/pubky-core.git
synced 2026-01-03 06:14:34 +01:00
chore: remove kytz package
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
[workspace]
|
||||
members = [
|
||||
"kytz",
|
||||
"mast",
|
||||
]
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
[package]
|
||||
name = "kytz"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "Soaring in the Cloud, but you pull the strings."
|
||||
license = "MIT"
|
||||
|
||||
[dependencies]
|
||||
argon2 = "0.5.2"
|
||||
bessie = "0.0.1"
|
||||
bytes = "1.5.0"
|
||||
rand = "0.8.5"
|
||||
thiserror = "1.0.50"
|
||||
z32 = "1.0.2"
|
||||
zeroize = "1.7.0"
|
||||
@@ -1,32 +0,0 @@
|
||||
//! Encryption functions.
|
||||
|
||||
use crate::{Error, Result};
|
||||
|
||||
use crate::crypto::Key;
|
||||
|
||||
/// Compute the length of a ciphertext, given the length of a plaintext.
|
||||
///
|
||||
/// This function returns `None` if the resulting ciphertext length would overflow a `u64`.
|
||||
pub fn ciphertext_len(plaintext_len: u64) -> Option<u64> {
|
||||
bessie::ciphertext_len(plaintext_len)
|
||||
}
|
||||
|
||||
/// Encrypt a message and write the ciphertext to an existing slice.
|
||||
///
|
||||
/// This function does not allocate memory. However, `ciphertext.len()` must be exactly equal to
|
||||
/// [`ciphertext_len(plaintext.len())`](ciphertext_len), or else this function will panic.
|
||||
pub fn encrypt_to_slice(key: &Key, plaintext: &[u8], ciphertext: &mut [u8]) {
|
||||
bessie::encrypt_to_slice(key, plaintext, ciphertext)
|
||||
}
|
||||
|
||||
/// Encrypt a message and return the ciphertext as a `Vec<u8>`.
|
||||
pub fn encrypt(key: &Key, plaintext: &[u8]) -> Vec<u8> {
|
||||
bessie::encrypt(key, plaintext)
|
||||
}
|
||||
|
||||
/// Decrypt a message and return the plaintext as `Result` of `Vec<u8>`.
|
||||
///
|
||||
/// If the ciphertext or key has been changed, decryption will return `Err`.
|
||||
pub fn decrypt(key: &Key, ciphertext: &[u8]) -> Result<Vec<u8>> {
|
||||
bessie::decrypt(key, ciphertext).map_err(|err| Error::Generic(err.to_string()))
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
pub mod encryption;
|
||||
pub mod passphrase;
|
||||
pub mod seed;
|
||||
|
||||
/// A 32 bytes key (encryption key or public key or shared_secret key).
|
||||
pub type Key = [u8; bessie::KEY_LEN];
|
||||
/// A 24 bytes Nonce or salt.
|
||||
pub type Nonce = [u8; bessie::NONCE_LEN];
|
||||
|
||||
/// Generate a random secret seed.
|
||||
pub fn generate_seed() -> Key {
|
||||
rand::random()
|
||||
}
|
||||
|
||||
/// Generate a random secret seed.
|
||||
pub fn generate_salt() -> Nonce {
|
||||
rand::random()
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,118 +0,0 @@
|
||||
//! Manage Kytz seed files.
|
||||
//!
|
||||
//! Seed file contains a seed encrypted with a strong passphrase.
|
||||
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use crate::{
|
||||
crypto::{
|
||||
encryption::{ciphertext_len, decrypt, encrypt_to_slice},
|
||||
Key,
|
||||
},
|
||||
Error, Result,
|
||||
};
|
||||
|
||||
const SEED_SCHEME: &[u8] = b"kytz:seed:";
|
||||
|
||||
const VERSION: u8 = 0;
|
||||
|
||||
/// Encrypt the seed with a strong passphrase, and return an [encrypted seed
|
||||
/// file](../../../design/seed.md).
|
||||
pub fn encrypt_seed(seed: &Key, passphrase: &str) -> Bytes {
|
||||
let mut encryption_key = derive_encryption_key(passphrase);
|
||||
|
||||
let mut seed_file = BytesMut::with_capacity(SEED_SCHEME.len() + 33);
|
||||
seed_file.extend_from_slice(SEED_SCHEME);
|
||||
|
||||
let suffix_len = 1 + ciphertext_len(seed.len() as u64).unwrap() as usize;
|
||||
let mut suffix = vec![0_u8; suffix_len];
|
||||
|
||||
suffix[0] = VERSION;
|
||||
encrypt_to_slice(&encryption_key, seed, &mut suffix[1..]);
|
||||
|
||||
seed_file.extend_from_slice(z32::encode(&suffix).as_bytes());
|
||||
|
||||
encryption_key.zeroize();
|
||||
|
||||
seed_file.freeze()
|
||||
}
|
||||
|
||||
/// Decrypt the [seed file](../../../design/seed.md).
|
||||
pub fn decrypt_seed(seed_file: Bytes, passphrase: &str) -> Result<Vec<u8>> {
|
||||
if !seed_file.starts_with(SEED_SCHEME) {
|
||||
return Err(Error::Generic("Not a Kytz seed".to_string()));
|
||||
}
|
||||
|
||||
let suffix = z32::decode(&seed_file[SEED_SCHEME.len()..])
|
||||
.map_err(|_| Error::Generic("Invalid seed encoding".to_string()))?;
|
||||
|
||||
let version = suffix[0];
|
||||
|
||||
match version {
|
||||
0 => decrypted_seed_v0(&suffix, passphrase),
|
||||
_ => Err(Error::Generic("Unknown Kytz seed file version".to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
fn decrypted_seed_v0(suffix: &[u8], passphrase: &str) -> Result<Vec<u8>> {
|
||||
let mut encryption_key = derive_encryption_key(passphrase);
|
||||
let encrypted_seed = &suffix[1..];
|
||||
|
||||
let decrypted_seed = decrypt(&encryption_key, encrypted_seed);
|
||||
|
||||
// Empty the encryption key in memory.
|
||||
encryption_key.zeroize();
|
||||
|
||||
decrypted_seed
|
||||
}
|
||||
|
||||
/// Derive a secret key from a strong passphrase for encrypting/decrypting the seed.
|
||||
fn derive_encryption_key(passphrase: &str) -> Key {
|
||||
// Argon2 with default params (Argon2id v19)
|
||||
let hasher = argon2::Argon2::default();
|
||||
|
||||
let mut encryption_key: Key = [0; 32];
|
||||
|
||||
hasher
|
||||
.hash_password_into(
|
||||
passphrase.as_bytes(),
|
||||
// While this is technically a Nonce reuse, it should not be a problem
|
||||
// since the encryption key is never shared or stored anywhere.
|
||||
SEED_SCHEME,
|
||||
&mut encryption_key,
|
||||
)
|
||||
// There shouldn't be any error, as we use the default params.
|
||||
.unwrap();
|
||||
|
||||
encryption_key
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::time::Instant;
|
||||
|
||||
use super::*;
|
||||
use crate::crypto::passphrase::*;
|
||||
use crate::crypto::*;
|
||||
|
||||
#[test]
|
||||
fn test_encrypt_decrypt_seed() {
|
||||
let seed = generate_seed();
|
||||
let passphrase = generate_4words_passphrase();
|
||||
|
||||
let encrypted_seed_file = encrypt_seed(&seed, &passphrase);
|
||||
|
||||
// dbg!(&encrypted_seed_file);
|
||||
|
||||
let start = Instant::now();
|
||||
let decrypted_seed = decrypt_seed(encrypted_seed_file, &passphrase)
|
||||
.expect("Failde to decrypt the seed file");
|
||||
|
||||
assert!(
|
||||
start.elapsed().as_millis() > 300,
|
||||
"decrypting the seed shouldn't be too fast"
|
||||
);
|
||||
assert_eq!(decrypted_seed, seed);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
//! Main Crate Error
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
/// Kytz crate error enum.
|
||||
pub enum Error {
|
||||
/// For starter, to remove as code matures.
|
||||
#[error("Generic error: {0}")]
|
||||
Generic(String),
|
||||
|
||||
#[error(transparent)]
|
||||
/// Error from `std::io::Error`.
|
||||
Io(#[from] std::io::Error),
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
// #![allow(unused)]
|
||||
pub mod crypto;
|
||||
pub mod error;
|
||||
|
||||
// Re-exports
|
||||
pub use error::Error;
|
||||
|
||||
// Alias Result to be the crate Result.
|
||||
pub type Result<T, E = Error> = core::result::Result<T, E>;
|
||||
Reference in New Issue
Block a user