Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "spectrex"
version = "0.3.19"
version = "0.3.20"
edition = "2021"
authors = ["Spectre developers"]
repository = "https://github.com/spectre-project/rusty-spectrex"
Expand All @@ -12,12 +12,12 @@ categories = ["algorithms", "cryptography"]
homepage = "https://spectre-network.org"

[dependencies]
cdivsufsort = "2.0.0"
fnv = "1.0.7"
rc4 = "0.1.0"
salsa20 = "0.10.2"
sha2 = "0.10.8"
siphasher = "1.0.1"
suffix_array = "0.5.0"
xxhash-rust = { version = "0.8.10", features = ["xxh64"] }

[dev-dependencies]
Expand Down
8 changes: 2 additions & 6 deletions benches/astrobwtv3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,9 @@ fn astrobwtv3_bench(input: &[u8; 32]) {
}

fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("astrobwtv3_zeros", |b| {
b.iter(|| astrobwtv3_bench(&[0; 32]))
});
c.bench_function("astrobwtv3_zeros", |b| b.iter(|| astrobwtv3_bench(&[0; 32])));

c.bench_function("astrobwtv3_ones", |b| {
b.iter(|| astrobwtv3_bench(&[0xFF; 32]))
});
c.bench_function("astrobwtv3_ones", |b| b.iter(|| astrobwtv3_bench(&[0xFF; 32])));

c.bench_function("astrobwtv3_random", |b| {
let random_data = random::<[u8; 32]>();
Expand Down
6 changes: 6 additions & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
max_width = 135
use_field_init_shorthand = true
use_try_shorthand = true
use_small_heuristics = "Max"
newline_style = "auto"
edition = "2021"
89 changes: 32 additions & 57 deletions src/astrobwtv3.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
// Public crates.
use cdivsufsort::sort_in_place as dss;
use rc4::{KeyInit, Rc4, StreamCipher};
use salsa20::{cipher::KeyIvInit, Salsa20};
use sha2::{Digest, Sha256};
use siphasher::sip::SipHasher24;
use std::hash::Hasher;
use suffix_array::SuffixArray;
use std::slice::from_raw_parts_mut;

// This is the maximum.
const MAX_LENGTH: u32 = (256 * 384) - 1;

// The base for the following code was contributed by @Wolf9466 on Discord.
#[rustfmt::skip]
const BRANCH_TABLE: [u32; 256] = [
0x090F020A, 0x060B0500, 0x09080609, 0x0A0D030B, 0x04070A01, 0x09030607, 0x060D0401, 0x000A0904,
0x040F0F06, 0x030E070C, 0x04020D02, 0x0B0F050A, 0x0C020C04, 0x0B03070F, 0x07060206, 0x0C060501,
Expand Down Expand Up @@ -123,57 +125,23 @@ pub fn astrobwtv3_hash(input: &[u8]) -> [u8; 32] {
for j in (0..=3).rev() {
let op = (opcode >> (j * 8)) & 0xFF;
match op {
0x00 => {
tmp = tmp.wrapping_add(tmp); // +
}
0x01 => {
tmp = tmp.wrapping_sub(tmp ^ 97); // XOR and -
}
0x02 => {
tmp = tmp.wrapping_mul(tmp); // *
}
0x03 => {
tmp ^= data[pos2 as usize]; // XOR
}
0x04 => {
tmp = !tmp; // binary NOT operator
}
0x05 => {
tmp &= data[pos2 as usize]; // AND
}
0x06 => {
tmp = tmp.wrapping_shl((tmp & 3) as u32); // shift left
}
0x07 => {
tmp = tmp.wrapping_shr((tmp & 3) as u32); // shift right
}
0x08 => {
tmp = tmp.reverse_bits(); // reverse bits
}
0x09 => {
tmp = tmp ^ tmp.count_ones() as u8; // ones count bits
}
0x0A => {
tmp = tmp.rotate_left(tmp as u32); // rotate bits by random
}
0x0B => {
tmp = tmp.rotate_left(1); // rotate bits by 1
}
0x0C => {
tmp = tmp ^ tmp.rotate_left(2); // rotate bits by 2
}
0x0D => {
tmp = tmp.rotate_left(3); // rotate bits by 3
}
0x0E => {
tmp = tmp ^ tmp.rotate_left(4); // rotate bits by 4
}
0x0F => {
tmp = tmp.rotate_left(5); // rotate bits by 5
}
_ => {
unreachable!();
}
0x00 => tmp = tmp.wrapping_add(tmp), // +
0x01 => tmp = tmp.wrapping_sub(tmp ^ 97), // XOR and -
0x02 => tmp = tmp.wrapping_mul(tmp), // *
0x03 => tmp ^= data[pos2 as usize], // XOR
0x04 => tmp = !tmp, // binary NOT operator
0x05 => tmp &= data[pos2 as usize], // AND
0x06 => tmp = tmp.wrapping_shl((tmp & 3) as u32), // shift left
0x07 => tmp = tmp.wrapping_shr((tmp & 3) as u32), // shift right
0x08 => tmp = tmp.reverse_bits(), // reverse bits
0x09 => tmp = tmp ^ tmp.count_ones() as u8, // ones count bits
0x0A => tmp = tmp.rotate_left(tmp as u32), // rotate bits by random
0x0B => tmp = tmp.rotate_left(1), // rotate bits by 1
0x0C => tmp = tmp ^ tmp.rotate_left(2), // rotate bits by 2
0x0D => tmp = tmp.rotate_left(3), // rotate bits by 3
0x0E => tmp = tmp ^ tmp.rotate_left(4), // rotate bits by 4
0x0F => tmp = tmp.rotate_left(5), // rotate bits by 5
_ => unreachable!(),
}
}
data[i as usize] = tmp;
Expand Down Expand Up @@ -233,13 +201,20 @@ pub fn astrobwtv3_hash(input: &[u8]) -> [u8; 32] {
}

// We may discard up to ~ 1KiB data from the stream to ensure that wide number of variants exists.
let data_len = (tries - 4) as u32 * 256
+ ((((data[253] as u64) << 8) | (data[254] as u64)) as u32 & 0x3ff);
let data_len = (tries - 4) as u32 * 256 + ((((data[253] as u64) << 8) | (data[254] as u64)) as u32 & 0x3ff);

// Step 6: build our suffix array.
let scratch_sa = SuffixArray::new(&scratch_data[..data_len as usize]);
let mut scratch_sa_bytes: Vec<u8> = vec![];
for vector in &scratch_sa.into_parts().1[1..(data_len as usize + 1)] {
let mut sa = vec![0u32; data_len as usize + 1];
sa[0] = data_len;

// i32 slice for cdivsufsort
let sa_i32 = unsafe { from_raw_parts_mut(sa[1..].as_mut_ptr() as *mut i32, data_len as usize) };

// Build suffix array
dss(&scratch_data[..data_len as usize], sa_i32);

let mut scratch_sa_bytes: Vec<u8> = Vec::with_capacity(data_len as usize * 4);
for vector in &sa[1..(data_len as usize + 1)] {
// Little and big endian.
if cfg!(target_endian = "little") {
scratch_sa_bytes.extend_from_slice(&vector.to_le_bytes());
Expand Down
102 changes: 22 additions & 80 deletions tests/astrobwtv3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,91 +2,33 @@
use spectrex::astrobwtv3;

// Source hashes.
#[rustfmt::skip]
const INPUT_HASHES: [[u8; 32]; 10] = [
[
88, 101, 183, 41, 212, 156, 190, 48, 230, 97, 94, 105, 177, 86, 88, 84, 60, 239, 203, 124,
63, 32, 160, 222, 34, 141, 50, 108, 138, 16, 90, 230,
],
[
131, 190, 160, 208, 86, 121, 144, 207, 78, 235, 188, 253, 251, 0, 62, 161, 72, 225, 55,
184, 202, 212, 91, 125, 56, 204, 174, 214, 100, 28, 150, 15,
],
[
179, 131, 188, 255, 206, 72, 67, 215, 143, 44, 37, 210, 230, 54, 1, 114, 91, 104, 33, 126,
162, 70, 130, 110, 176, 105, 75, 122, 212, 119, 158, 216,
],
[
39, 225, 250, 46, 101, 197, 139, 171, 106, 53, 239, 59, 245, 146, 31, 67, 140, 201, 190,
86, 193, 24, 88, 104, 86, 69, 166, 231, 214, 240, 167, 63,
],
[
245, 133, 43, 254, 160, 213, 125, 60, 90, 42, 50, 123, 188, 209, 219, 125, 176, 250, 51,
158, 201, 167, 122, 244, 98, 108, 163, 110, 66, 26, 110, 177,
],
[
209, 138, 166, 16, 5, 177, 37, 64, 133, 13, 211, 172, 189, 223, 107, 148, 194, 78, 132, 23,
181, 25, 69, 149, 229, 95, 41, 73, 236, 217, 1, 119,
],
[
74, 36, 121, 180, 94, 215, 192, 195, 231, 0, 113, 44, 66, 171, 214, 173, 223, 29, 224, 201,
26, 217, 139, 162, 153, 31, 15, 158, 221, 165, 97, 74,
],
[
49, 189, 89, 13, 141, 86, 53, 198, 164, 148, 121, 198, 40, 219, 66, 13, 251, 73, 38, 16,
94, 71, 244, 44, 236, 119, 243, 202, 211, 199, 161, 164,
],
[
36, 23, 55, 103, 91, 244, 203, 137, 143, 244, 115, 22, 197, 152, 241, 34, 94, 40, 61, 246,
64, 251, 232, 23, 91, 203, 48, 233, 13, 70, 19, 6,
],
[
19, 247, 78, 146, 5, 164, 136, 199, 248, 218, 200, 24, 110, 186, 2, 253, 192, 139, 161, 70,
92, 156, 177, 77, 63, 124, 209, 236, 105, 130, 229, 218,
],
[88, 101, 183, 41, 212, 156, 190, 48, 230, 97, 94, 105, 177, 86, 88, 84, 60, 239, 203, 124, 63, 32, 160, 222, 34, 141, 50, 108, 138, 16, 90, 230],
[131, 190, 160, 208, 86, 121, 144, 207, 78, 235, 188, 253, 251, 0, 62, 161, 72, 225, 55, 184, 202, 212, 91, 125, 56, 204, 174, 214, 100, 28, 150, 15],
[179, 131, 188, 255, 206, 72, 67, 215, 143, 44, 37, 210, 230, 54, 1, 114, 91, 104, 33, 126, 162, 70, 130, 110, 176, 105, 75, 122, 212, 119, 158, 216],
[39, 225, 250, 46, 101, 197, 139, 171, 106, 53, 239, 59, 245, 146, 31, 67, 140, 201, 190, 86, 193, 24, 88, 104, 86, 69, 166, 231, 214, 240, 167, 63],
[245, 133, 43, 254, 160, 213, 125, 60, 90, 42, 50, 123, 188, 209, 219, 125, 176, 250, 51, 158, 201, 167, 122, 244, 98, 108, 163, 110, 66, 26, 110, 177],
[209, 138, 166, 16, 5, 177, 37, 64, 133, 13, 211, 172, 189, 223, 107, 148, 194, 78, 132, 23, 181, 25, 69, 149, 229, 95, 41, 73, 236, 217, 1, 119],
[74, 36, 121, 180, 94, 215, 192, 195, 231, 0, 113, 44, 66, 171, 214, 173, 223, 29, 224, 201, 26, 217, 139, 162, 153, 31, 15, 158, 221, 165, 97, 74],
[49, 189, 89, 13, 141, 86, 53, 198, 164, 148, 121, 198, 40, 219, 66, 13, 251, 73, 38, 16, 94, 71, 244, 44, 236, 119, 243, 202, 211, 199, 161, 164],
[36, 23, 55, 103, 91, 244, 203, 137, 143, 244, 115, 22, 197, 152, 241, 34, 94, 40, 61, 246, 64, 251, 232, 23, 91, 203, 48, 233, 13, 70, 19, 6],
[19, 247, 78, 146, 5, 164, 136, 199, 248, 218, 200, 24, 110, 186, 2, 253, 192, 139, 161, 70, 92, 156, 177, 77, 63, 124, 209, 236, 105, 130, 229, 218]
];

// Expected hashes.
#[rustfmt::skip]
const OUTPUT_HASHES: [[u8; 32]; 10] = [
[
245, 38, 108, 237, 82, 247, 189, 19, 237, 82, 86, 55, 2, 184, 61, 119, 46, 92, 244, 227,
116, 149, 198, 219, 96, 114, 78, 176, 95, 100, 70, 108,
],
[
253, 32, 214, 213, 188, 194, 70, 228, 112, 24, 6, 44, 126, 57, 113, 161, 136, 239, 160,
105, 186, 240, 50, 226, 251, 170, 152, 240, 56, 198, 210, 155,
],
[
65, 74, 3, 63, 226, 164, 225, 88, 106, 53, 218, 166, 144, 241, 106, 229, 179, 70, 126, 4,
251, 123, 47, 222, 21, 59, 215, 107, 158, 120, 220, 231,
],
[
155, 216, 182, 230, 186, 65, 127, 57, 112, 0, 112, 151, 217, 159, 28, 9, 108, 203, 111,
197, 28, 57, 187, 106, 119, 43, 187, 152, 185, 232, 76, 39,
],
[
142, 168, 196, 185, 54, 135, 241, 38, 229, 163, 12, 77, 61, 148, 126, 102, 91, 39, 191,
175, 181, 12, 18, 132, 39, 161, 222, 157, 170, 145, 13, 135,
],
[
35, 178, 78, 186, 52, 161, 140, 179, 209, 163, 146, 6, 40, 117, 215, 227, 154, 174, 92,
246, 212, 77, 96, 243, 94, 87, 135, 193, 151, 155, 220, 19,
],
[
176, 117, 190, 212, 164, 159, 17, 220, 116, 184, 102, 106, 61, 148, 204, 230, 46, 171, 41,
20, 214, 91, 151, 11, 48, 93, 240, 8, 37, 189, 240, 125,
],
[
60, 248, 1, 238, 24, 248, 240, 206, 56, 147, 254, 66, 226, 246, 107, 22, 164, 135, 124, 15,
102, 244, 33, 117, 126, 87, 71, 160, 243, 245, 34, 38,
],
[
76, 190, 131, 164, 182, 28, 224, 104, 232, 94, 56, 15, 28, 185, 196, 63, 149, 235, 83, 228,
139, 1, 112, 29, 30, 83, 30, 92, 29, 71, 75, 217,
],
[
147, 234, 41, 103, 132, 162, 41, 23, 249, 180, 98, 124, 32, 81, 107, 133, 162, 73, 44, 135,
179, 55, 228, 194, 113, 179, 161, 235, 85, 5, 111, 121,
],
[245, 38, 108, 237, 82, 247, 189, 19, 237, 82, 86, 55, 2, 184, 61, 119, 46, 92, 244, 227, 116, 149, 198, 219, 96, 114, 78, 176, 95, 100, 70, 108],
[253, 32, 214, 213, 188, 194, 70, 228, 112, 24, 6, 44, 126, 57, 113, 161, 136, 239, 160, 105, 186, 240, 50, 226, 251, 170, 152, 240, 56, 198, 210, 155],
[65, 74, 3, 63, 226, 164, 225, 88, 106, 53, 218, 166, 144, 241, 106, 229, 179, 70, 126, 4, 251, 123, 47, 222, 21, 59, 215, 107, 158, 120, 220, 231],
[155, 216, 182, 230, 186, 65, 127, 57, 112, 0, 112, 151, 217, 159, 28, 9, 108, 203, 111, 197, 28, 57, 187, 106, 119, 43, 187, 152, 185, 232, 76, 39],
[142, 168, 196, 185, 54, 135, 241, 38, 229, 163, 12, 77, 61, 148, 126, 102, 91, 39, 191, 175, 181, 12, 18, 132, 39, 161, 222, 157, 170, 145, 13, 135],
[35, 178, 78, 186, 52, 161, 140, 179, 209, 163, 146, 6, 40, 117, 215, 227, 154, 174, 92, 246, 212, 77, 96, 243, 94, 87, 135, 193, 151, 155, 220, 19],
[176, 117, 190, 212, 164, 159, 17, 220, 116, 184, 102, 106, 61, 148, 204, 230, 46, 171, 41, 20, 214, 91, 151, 11, 48, 93, 240, 8, 37, 189, 240, 125],
[60, 248, 1, 238, 24, 248, 240, 206, 56, 147, 254, 66, 226, 246, 107, 22, 164, 135, 124, 15, 102, 244, 33, 117, 126, 87, 71, 160, 243, 245, 34, 38],
[76, 190, 131, 164, 182, 28, 224, 104, 232, 94, 56, 15, 28, 185, 196, 63, 149, 235, 83, 228, 139, 1, 112, 29, 30, 83, 30, 92, 29, 71, 75, 217],
[147, 234, 41, 103, 132, 162, 41, 23, 249, 180, 98, 124, 32, 81, 107, 133, 162, 73, 44, 135, 179, 55, 228, 194, 113, 179, 161, 235, 85, 5, 111, 121]
];

// AstroBWTv3 tests.
Expand Down