1use std::num::ParseIntError;
18
19use crate::hash::TequelHash;
20use crate::error::TequelError;
21use crate::rng::TequelRng;
22
23#[cfg(target_arch = "x86_64")]
24use std::arch::x86_64::*;
25
26use crate::avx2_inline::{ add_i8, xor, storeu, loadu, sub_i8, setone_i32 };
27
28use zeroize::{Zeroize, ZeroizeOnDrop};
29
30#[cfg(feature = "serde")]
31use serde::{Serialize, Deserialize};
32
33
34#[derive(Debug, Zeroize, ZeroizeOnDrop, Clone, PartialEq, Eq)]
45#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
46pub struct TequelEncrypt {
47 pub salt: String,
48 pub iterations: u32,
49}
50
51
52#[derive(Debug, Zeroize, ZeroizeOnDrop, Clone, PartialEq, Eq)]
68#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
69pub struct TequelEncryption {
70 pub encrypted_data: String,
71 pub salt: String,
72 pub mac: String
73}
74
75
76
77impl TequelEncrypt {
78
79 pub fn new() -> Self {
80 Self {
81 salt: "".to_string(),
82 iterations: 30
83 }
84 }
85
86 pub fn with_salt(mut self, salt: &str) -> Self {
87 self.salt = salt.to_string();
88 self
89 }
90
91 pub fn with_iteration(mut self, value: u32) -> Self{
92 self.iterations = value;
93 self
94 }
95
96 pub fn encrypt(&mut self, data: &[u8], key: &str) -> Result<TequelEncryption, TequelError> {
135
136 if self.salt.as_bytes().len() == 0 {
138 let tequel_rng = TequelRng::new();
139 self.salt = tequel_rng.rand_by_nano().to_string();
140 }
141
142 let key_salt = self.salt.as_bytes(); let key_crypt = key.as_bytes(); if key_crypt.len() == 0 {
147 return Err(TequelError::KeyError("Key is empty".to_string()))
148 }
149
150 let a = 0x107912fau32.to_be_bytes(); let b = 0x220952eau32.to_be_bytes(); let c = 0x3320212au32.to_be_bytes(); let d = 0x4324312fu32.to_be_bytes(); let e = 0x5320212au32.to_be_bytes(); let mut res_bytes = Vec::with_capacity(data.len());
157
158 let val_a = u32::from_be_bytes(a);
159 let val_b = u32::from_be_bytes(b);
160 let val_c = u32::from_be_bytes(c);
161 let val_d = u32::from_be_bytes(d);
162 let val_e = u32::from_be_bytes(e);
163
164 unsafe {
166
167 if is_x86_feature_detected!("avx2") {
168
169 let chunks = data.chunks_exact(32);
170 let remainder = chunks.remainder();
171
172
173 let ymm_c_a = setone_i32(val_a as i32);
174 let ymm_c_b = setone_i32(val_b as i32);
175 let ymm_c_c = setone_i32(val_c as i32);
176 let ymm_c_d = setone_i32(val_d as i32);
177 let ymm_c_e = setone_i32(val_e as i32);
178
179
180 for (c_idx, chunk) in chunks.enumerate() {
181
182 let byte_offset = c_idx * 32; let mut ymm1 = loadu(chunk.as_ptr() as *const __m256i);
184
185
186
187 ymm1 = add_i8(ymm1, ymm_c_a);
188 ymm1 = xor(ymm1, ymm_c_b);
189 ymm1 = add_i8(ymm1, ymm_c_c);
190 ymm1 = xor(ymm1, ymm_c_d);
191 ymm1 = add_i8(ymm1, ymm_c_e);
192
193
194
195 let mut expanded_key = [0u8; 32];
196
197 for i in 0..32 {
198 expanded_key[i] = key_crypt[(byte_offset + i) % key_crypt.len()];
199 }
200
201 ymm1 = xor(ymm1, loadu(expanded_key.as_ptr() as *const __m256i));
202
203
204
205
206 let mut out = [0u8; 32];
207 storeu(out.as_mut_ptr() as *mut __m256i, ymm1);
208
209 res_bytes.extend_from_slice(&out);
210
211 }
212
213 let processed_bytes = data.len() - remainder.len();
214
215 for (i, &byte) in remainder.iter().enumerate() {
216
217 let g_idx = processed_bytes + i;
218 let mut curr = byte;
219
220 curr = curr.wrapping_add(a[g_idx % 4]);
221 curr = curr ^ b[g_idx % 4];
222 curr = curr.wrapping_add(c[g_idx % 4]);
223 curr = curr ^ d[g_idx % 4];
224 curr = curr.wrapping_add(e[g_idx % 4]);
225
226 curr = curr ^ key_crypt[g_idx % key_crypt.len()];
227
228 res_bytes.push(curr)
229
230 }
231
232 }
233 }
234
235
236
237 let res = res_bytes.iter()
238 .map(|b| format!("{:02x}", b))
239 .collect::<String>();
240
241 let salt_res = key_salt.iter()
242 .map(|b| format!("{:02x}", b))
243 .collect::<String>();
244
245
246 let mut mixmac_buffer = Vec::with_capacity(20 + res_bytes.len() + key_salt.len() + key_crypt.len());
247
248 mixmac_buffer.extend_from_slice(&a);
249 mixmac_buffer.extend_from_slice(&res_bytes);
250 mixmac_buffer.extend_from_slice(&b);
251 mixmac_buffer.extend_from_slice(&c);
252 mixmac_buffer.extend_from_slice(&salt_res.as_bytes());
253 mixmac_buffer.extend_from_slice(&d);
254 mixmac_buffer.extend_from_slice(&key_crypt);
255 mixmac_buffer.extend_from_slice(&e);
256
257 let mut cus_teq_hash = TequelHash::new();
258 let comb_mixmac = cus_teq_hash.tqlhash(&mixmac_buffer).to_lowercase();
259
260
261 Ok(TequelEncryption { encrypted_data: res, salt: salt_res, mac: comb_mixmac })
262
263 }
264
265
266 pub fn decrypt(&mut self, tequel_encryption: &TequelEncryption, key: &str) -> Result<String, TequelError> {
311
312 if key.is_empty() { return Err(TequelError::KeyError("Key is empty".to_string())); }
313
314 let a = 0x107912fau32.to_be_bytes(); let b = 0x220952eau32.to_be_bytes(); let c = 0x3320212au32.to_be_bytes(); let d = 0x4324312fu32.to_be_bytes(); let e = 0x5320212au32.to_be_bytes(); let encrypted_data = self.decode_hex(&tequel_encryption.encrypted_data).map_err(|e| {
323 TequelError::InvalidHex(e.to_string())
324 })?;
325
326 let salt_hex = self.decode_hex(&tequel_encryption.salt).map_err(|e| {
327 TequelError::InvalidHex(e.to_string())
328 })?;
329
330 let mut mixmac_buffer = Vec::with_capacity(20 + encrypted_data.len() + tequel_encryption.salt.len() + key.len());
331
332 mixmac_buffer.extend_from_slice(&a);
333 mixmac_buffer.extend_from_slice(&encrypted_data);
334 mixmac_buffer.extend_from_slice(&b);
335 mixmac_buffer.extend_from_slice(&c);
336 mixmac_buffer.extend_from_slice(&tequel_encryption.salt.as_bytes());
337 mixmac_buffer.extend_from_slice(&d);
338 mixmac_buffer.extend_from_slice(&key.as_bytes());
339 mixmac_buffer.extend_from_slice(&e);
340
341 let mut cus_teq_hash = TequelHash::new();
342 let comb_mixmac = cus_teq_hash.tqlhash(&mixmac_buffer).to_lowercase();
343
344 let is_valid = self.compare_macs(tequel_encryption.mac.to_lowercase().as_bytes(), comb_mixmac.as_bytes());
345
346 if !is_valid {
347 return Err(TequelError::InvalidMac);
348 }
349
350 let encrypted_data = self.decode_hex(&tequel_encryption.encrypted_data).map_err(|e| {
353 TequelError::InvalidHex(e.to_string())
354 })?;
355
356 let mut res_bytes = Vec::with_capacity(encrypted_data.len());
357 let key_encrypt_input = key.as_bytes();
358
359
360 let val_a = u32::from_be_bytes(a);
361 let val_b = u32::from_be_bytes(b);
362 let val_c = u32::from_be_bytes(c);
363 let val_d = u32::from_be_bytes(d);
364 let val_e = u32::from_be_bytes(e);
365
366 unsafe {
367
368 if is_x86_feature_detected!("avx2") {
369
370 let chunks = encrypted_data.chunks_exact(32);
371 let remainder = chunks.remainder();
372
373 let ymm_c_a = setone_i32(val_a as i32);
374 let ymm_c_b = setone_i32(val_b as i32);
375 let ymm_c_c = setone_i32(val_c as i32);
376 let ymm_c_d = setone_i32(val_d as i32);
377 let ymm_c_e = setone_i32(val_e as i32);
378
379 for (c_idx, chunk) in chunks.enumerate() {
380
381 let byte_offset = c_idx * 32;
382 let mut ymm1 = loadu(chunk.as_ptr() as *const __m256i);
383
384
385 let mut expanded_key = [0u8; 32];
386 for i in 0..32 {
387 expanded_key[i] = key_encrypt_input[(byte_offset + i) % key_encrypt_input.len()];
388 }
389
390 ymm1 = xor(ymm1, loadu(expanded_key.as_ptr() as *const __m256i));
391
392
393 ymm1 = sub_i8(ymm1, ymm_c_e);
394 ymm1 = xor(ymm1, ymm_c_d);
395 ymm1 = sub_i8(ymm1, ymm_c_c);
396 ymm1 = xor(ymm1, ymm_c_b);
397 ymm1 = sub_i8(ymm1, ymm_c_a);
398
399
400 let mut out = [0u8; 32];
401 storeu(out.as_mut_ptr() as *mut __m256i, ymm1);
402
403 res_bytes.extend_from_slice(&out);
404
405 }
406
407 let processed_bytes = encrypted_data.len() - remainder.len();
409
410 for (i, &byte) in remainder.iter().enumerate() {
411
412 let g_idx = processed_bytes + i;
413 let mut curr = byte;
414
415 curr ^= key_encrypt_input[g_idx % key_encrypt_input.len()];
416
417 curr = curr.wrapping_sub(e[g_idx % 4]);
418 curr ^= d[g_idx % 4];
419 curr = curr.wrapping_sub(c[g_idx % 4]);
420 curr ^= b[g_idx % 4];
421 curr = curr.wrapping_sub(a[g_idx % 4]);
422
423 res_bytes.push(curr)
424
425 }
426
427 }
428
429 }
430
431 let res = String::from_utf8(res_bytes).map_err(|_| TequelError::InvalidUtf8)?;
432
433 Ok(res)
434
435 }
436
437
438
439
440
441
442 fn decode_hex(&self, val: &str) -> Result<Vec<u8>, ParseIntError> {
443 if val.len() % 2 != 0 {
444 return Err("Hex string has an odd length".parse::<u8>().unwrap_err());
445 }
446
447 (0..val.len())
448 .step_by(2)
449 .map(|i| u8::from_str_radix(&val[i..i + 2], 16))
450 .collect()
451 }
452
453 fn compare_macs(&self, mac_a: &[u8], mac_b: &[u8]) -> bool {
454 let mut acc = 0;
455
456 for (i, &byte) in mac_a.iter().enumerate() {
457 acc = acc | byte ^ mac_b[i];
458 }
459
460 acc == 0
461 }
462}