xxblake3

encryption and decryption based on xxh3 and blake3

see tests/main.rs for usage

```rust use xxblake3::{decrypt, encrypt};

[test]

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);

assert_eq!(*data, *decrypt(&secret, &encrypted).unwrap());

encrypted[9] = !encrypted[9];

assert_eq!(None, decrypt(&secret, &encrypted)); }

```

impl code

```rust

![feature(new_uninit)]

use blake3::Hasher; use core::hash::Hasher as ; use std::convert::TryInto; use twoxhash::xxh3::{hash64, Hash64};

const LENU64: usize = std::mem::sizeof::(); const H64SEED: u64 = 18185519866219491_001;

[inline]

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]) -> OptionU64..]; let hash = u64::fromlebytes(data[..LENU64].tryinto().unwrap()) ^ hashdatasecret(ed, secret); let outlen = data.len() - LENU64; let mut out = unsafe { Box::<[u8]>::newuninitslice(outlen).assume_init() };

Hasher::new() .update(&hash.tolebytes()) .update(secret) .finalize_xof() .fill(&mut out);

xor!(out, ed);

if hash64(&out) != hash { None } else { Some(out) } }

```

step

加密流程 :

  1. 校验码 = xxh3::Hash64(原始内容) // seed = 0
  2. 流密码 = blake3(校验码+秘钥), 哈希输出长度=内容长度
  3. 加密内容 = 原始内容 异或 流密码
  4. 加密校验码 = xxh3::Hash64(加密内容+秘钥) 异或 校验码 // seed = 18185519866219491001
  5. 输出 = 加密校验码 + 加密内容

解密流程 :

  1. 校验码 = xxh3::Hash64(加密内容+秘钥) 异或 加密校验码 // seed = 18185519866219491001
  2. 流密码 = blake3(校验码+秘钥), 哈希输出长度=内容长度
  3. 解密内容 = 加密内容 异或 流密码
  4. 完整性效验 : 计算 xxh3::Hash64(解密内容) == 校验码 // seed = 0