#[cfg(any(target_arch = "x86", target_arch = "x86_64"))//, target_feature = "avx2") //all()
]
mod avx2;
mod opcode;
use avx2::*;
use opcode::*;
use std::{ptr, slice::from_raw_parts};
static mut WORD: u128 = 0u128;
const OPCODES: [unsafe fn(&mut XynthVM); 11] = [enc, dec, add, sub, div, mul, pal, sqr, mwr, mre, store];
pub struct XynthVM {
memory : Box<[u128]>, registers : Registers,
}
#[derive(PartialEq, Clone, Copy)]
pub enum HashLength {
H128, H256, H512, H1024, }
struct Registers {
rwr0 : m256i,
rwr1 : m256i,
rwr2 : m256d,
rwr3 : m256d,
aes0 : m128i,
aes1 : m128i,
}
impl Default for XynthVM {
fn default() -> Self {
Self::new()
}
}
impl XynthVM {
pub fn new() -> XynthVM {
XynthVM {
memory : [0u128; 16777216].to_vec().into_boxed_slice(), registers : Registers {
rwr0 : m256i::zero(),
rwr1 : m256i::zero(),
rwr2 : m256d::zero(),
rwr3 : m256d::zero(),
aes0 : m128i::zero(),
aes1 : m128i::zero(),
}
}
}
#[target_feature(enable = "avx2")]
pub unsafe fn hash(&mut self, keybytes: &[u8], length: HashLength, salt: Option<&[u8]>) -> Vec<u8> {
if salt.is_some() {
self.init_memory(&bitxor2vec(keybytes, salt.unwrap_unchecked()));
} else {
self.init_memory(keybytes);
}
let mut buffer: Vec<u8> = {
match length {
HashLength::H128 => Vec::<u8>::with_capacity(16),
HashLength::H256 => Vec::<u8>::with_capacity(32),
HashLength::H512 => Vec::<u8>::with_capacity(64),
HashLength::H1024 => Vec::<u8>::with_capacity(128),
}
};
let mut counter: usize = 0usize;
for p in 0usize..2_097_152_usize { WORD = self.memory[p];
let op: usize = ((WORD << 124) >> 124) as usize;
if let 0..=10 = op { OPCODES[op](self)
}
match length {
HashLength::H128 => {
if buffer.len() < 16 {
let u8arr: [u8; 16] = WORD.to_le_bytes();
append_fixed(&mut buffer, u8arr);
} else {
let u8arr: [u8; 16] = WORD.to_le_bytes();
if counter < 1 {
counter += 1
}
let mut order: usize = 0usize;
let chunk: [u8; 16] = {
from_raw_parts(buffer.as_ptr() as *mut [u8; 16], buffer.len())[counter-1]
};
let merged: [u8; 16] = bitxor2u8x16(chunk, u8arr);
for i in buffer.iter_mut().take(counter * 16).skip(counter * 16 - 16) {
*i = merged[order];
order += 1usize;
}
}
},
HashLength::H256 => {
if buffer.len() < 32 {
let u8arr: [u8; 16] = WORD.to_le_bytes();
append_fixed(&mut buffer, u8arr);
} else {
let u8arr: [u8; 16] = WORD.to_le_bytes();
if counter < 2 {
counter += 1
} else {
counter = 1;
}
let mut order: usize = 0usize;
let chunk: [u8; 16] = {
from_raw_parts(buffer.as_ptr() as *mut [u8; 16], buffer.len())[counter-1]
};
let merged: [u8; 16] = bitxor2u8x16(chunk, u8arr);
for i in buffer.iter_mut().take(counter * 16).skip(counter * 16 - 16) {
*i = merged[order];
order += 1usize;
}
}
},
HashLength::H512 => {
if buffer.len() < 64 {
let u8arr: [u8; 16] = WORD.to_le_bytes();
append_fixed(&mut buffer, u8arr);
} else {
let u8arr: [u8; 16] = WORD.to_le_bytes();
if counter < 4 {
counter += 1
} else {
counter = 1;
}
let mut order: usize = 0usize;
let chunk: [u8; 16] = {
from_raw_parts(buffer.as_ptr() as *mut [u8; 16], buffer.len())[counter-1]
};
let merged: [u8; 16] = bitxor2u8x16(chunk, u8arr);
for i in buffer.iter_mut().take(counter * 16).skip(counter * 16 - 16) {
*i = merged[order];
order += 1usize;
}
}
},
HashLength::H1024 => {
if buffer.len() < 128 {
let u8arr: [u8; 16] = WORD.to_le_bytes();
append_fixed(&mut buffer, u8arr);
} else {
let u8arr: [u8; 16] = WORD.to_le_bytes();
if counter < 8 {
counter += 1
} else {
counter = 1;
}
let mut order: usize = 0usize;
let chunk: [u8; 16] = {
from_raw_parts(buffer.as_ptr() as *mut [u8; 16], buffer.len())[counter-1]
};
let merged: [u8; 16] = bitxor2u8x16(chunk, u8arr);
for i in buffer.iter_mut().take(counter * 16).skip(counter * 16 - 16) {
*i = merged[order];
order += 1usize;
}
}
}
}
}
buffer
}
#[target_feature(enable = "avx2")]
unsafe fn init_memory(&mut self, seed: &[u8]) {
let mut base: u128 = arrsum(seed);
let mut revrs: u128;
let mut secn: u128;
for i in &mut self.memory {
revrs = 0u128;
secn = base;
while secn > 0 {
revrs = (revrs << 3) + (revrs << 1) + secn % 10 ;
secn /= 10;
}
base = base.wrapping_add(revrs);
*i = base;
}
}
}
#[target_feature(enable = "avx2")]
const unsafe fn arrsum(arr: &[u8]) -> u128 {
let mut sum: u128 = 0u128;
let mut clock: usize = 0usize;
while clock < arr.len() {
sum = sum.wrapping_add(arr[clock] as u128);
clock += 1
}
sum
}
#[target_feature(enable = "avx2")]
unsafe fn bitxor2vec(a: &[u8], b: &[u8]) -> Vec<u8> {
let mut result: Vec<u8> = Vec::<u8>::with_capacity(a.len().abs_diff(b.len())+a.len());
let mut buf: u8;
for (aval, bval) in a.iter().zip(b) {
buf = aval ^ bval;
result.push((buf >> 4) + (buf << 4));
}
for i in 0..result.len() - 1 {
result[i] ^= result[i+1];
}
result
}
#[target_feature(enable = "avx2")]
const unsafe fn bitxor2u8x16(mut a: [u8; 16], b: [u8; 16]) -> [u8; 16] {
let mut clock: usize = 0usize;
while clock < 16 {
a[clock] ^= b[clock];
clock += 1
}
clock = 0;
while clock < 15 {
a[clock] ^= a[clock+1];
clock += 1
}
a
}
unsafe fn append_fixed(that: &mut Vec<u8>, other: [u8; 16]) {
core::hint::assert_unchecked(that.capacity() >= that.len());
let mut clock: usize = 0usize;
while clock < 16 {
let len: usize = that.len();
ptr::write(that.as_mut_ptr().add(len), other[clock]);
clock += 1;
that.set_len(len + 1);
}
}