Migrate from bincode to rkyv
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-12-29 16:20:01 +01:00
parent b0667312e5
commit c850288d85
4 changed files with 451 additions and 387 deletions

View File

@@ -2,15 +2,21 @@ use aes_gcm::aead::{Aead, OsRng};
use aes_gcm::{Aes256Gcm, Key, KeyInit, Nonce};
use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
use base64::Engine as _;
use bincode::{Decode, Encode};
use rand::Rng;
use rkyv::api::high::{HighSerializer, HighValidator};
use rkyv::bytecheck::CheckBytes;
use rkyv::de::Pool;
use rkyv::rancor::Strategy;
use rkyv::ser::allocator::ArenaHandle;
use rkyv::util::AlignedVec;
use rkyv::{Archive, Deserialize, Serialize};
use std::error::Error;
/// The lenght of the nonce used to initialize encryption
/// The length of the nonce used to initialize encryption
const NONCE_LEN: usize = 12;
/// CryptoWrapper is a library that can be used to encrypt and decrypt some data marked
/// that derives [Encode] and [Decode] traits using AES encryption
/// that derives [SchemaWrite] and [SchemaRead] traits using AES encryption
pub struct CryptoWrapper {
key: Key<Aes256Gcm>,
}
@@ -24,11 +30,14 @@ impl CryptoWrapper {
}
/// Encrypt some data, returning the result as a base64-encoded string
pub fn encrypt<T: Encode + Decode<()>>(&self, data: &T) -> Result<String, Box<dyn Error>> {
pub fn encrypt(
&self,
data: &impl for<'a> Serialize<HighSerializer<AlignedVec, ArenaHandle<'a>, rkyv::rancor::Error>>,
) -> Result<String, Box<dyn Error>> {
let aes_key = Aes256Gcm::new(&self.key);
let nonce_bytes = rand::rng().random::<[u8; NONCE_LEN]>();
let serialized_data = bincode::encode_to_vec(data, bincode::config::standard())?;
let serialized_data = rkyv::to_bytes(data)?;
let mut enc = aes_key
.encrypt(Nonce::from_slice(&nonce_bytes), serialized_data.as_slice())
@@ -39,7 +48,12 @@ impl CryptoWrapper {
}
/// Decrypt some data previously encrypted using the [`CryptoWrapper::encrypt`] method
pub fn decrypt<T: Decode<()>>(&self, input: &str) -> Result<T, Box<dyn Error>> {
pub fn decrypt<T>(&self, input: &str) -> Result<T, Box<dyn Error>>
where
T: Archive,
T::Archived: for<'a> CheckBytes<HighValidator<'a, rkyv::rancor::Error>>
+ Deserialize<T, Strategy<Pool, rkyv::rancor::Error>>,
{
let bytes = BASE64_STANDARD.decode(input)?;
if bytes.len() < NONCE_LEN {
@@ -63,16 +77,15 @@ impl CryptoWrapper {
}
};
Ok(bincode::decode_from_slice(&dec, bincode::config::standard())?.0)
Ok(rkyv::from_bytes(&dec)?)
}
}
#[cfg(test)]
mod test {
use crate::crypto_wrapper::CryptoWrapper;
use bincode::{Decode, Encode};
#[derive(Encode, Decode, Eq, PartialEq, Debug)]
#[derive(Eq, PartialEq, Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
struct Message(String);
#[test]