encryption and decryption based on xxh3 and blake3
see tests/main.rs for usage
```rust use xxblake3::{decrypt, encrypt};
fn main() { let secret = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, ];
let data = "test msg".as_bytes();
let mut encrypted = encrypt(&secret, data);
println!("data len {}", data.len()); println!("encrypted len {}", encrypted.len());
assert_eq!(*data, *decrypt(&secret, &encrypted).unwrap());
encrypted[9] = !encrypted[9];
assert_eq!(None, decrypt(&secret, &encrypted)); }
```
impl code
```rust
use blake3::Hasher; use core::hash::Hasher as ; use std::convert::TryInto; use twoxhash::xxh3::{hash64, Hash64};
const LENU64: usize = std::mem::sizeof::
pub fn hashdatasecret(secret: &[u8], data: &[u8]) -> u64 { let mut h64 = Hash64::withseed(H64SEED); h64.write(data); h64.write(secret); h64.finish() }
macrorules! xor { ($out:expr, $x:expr) => { $out.itermut().zip($x.iter()).for_each(|(a, b)| *a ^= *b); }; }
pub fn encrypt(secret: &[u8], data: &[u8]) -> Box<[u8]> { let hash = hash64(data);
let outlen = LENU64 + data.len(); let mut out = unsafe { Box::<[u8]>::newuninitslice(outlen).assumeinit() }; let outdata = &mut out[LENU64..];
Hasher::new() .update(&hash.tolebytes()) .update(secret) .finalizexof() .fill(outdata);
xor!(out_data, data);
let hash = hashdatasecret(out_data, secret) ^ hash;
out[..LENU64].clonefromslice(&hash.tole_bytes());
out }
pub fn decrypt(secret: &[u8], data: &[u8]) -> Option
Hasher::new() .update(&hash.tolebytes()) .update(secret) .finalize_xof() .fill(&mut out);
xor!(out, ed);
if hash64(&out) != hash { None } else { Some(out) } }
```
加密流程 :
解密流程 :