From 0b57c2e9bb4c534d60799ea787de6a2a0842276e Mon Sep 17 00:00:00 2001 From: koniifer Date: Sun, 24 Nov 2024 20:58:14 +0000 Subject: [PATCH] simple foldhash implementation --- Cargo.lock | 6 +- kernel/src/kmain.rs | 2 +- sysdata/libraries/stn/src/hash/foldhash.hb | 189 +++++++++++++++++++++ sysdata/libraries/stn/src/hash/lib.hb | 2 + sysdata/libraries/stn/src/lib.hb | 1 + sysdata/programs/hash_test/meta.toml | 11 ++ sysdata/programs/hash_test/src/main.hb | 31 ++++ sysdata/system_config.toml | 5 +- 8 files changed, 242 insertions(+), 5 deletions(-) create mode 100644 sysdata/libraries/stn/src/hash/foldhash.hb create mode 100644 sysdata/libraries/stn/src/hash/lib.hb create mode 100644 sysdata/programs/hash_test/meta.toml create mode 100644 sysdata/programs/hash_test/src/main.hb diff --git a/Cargo.lock b/Cargo.lock index 45ec401..02fc4ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -213,12 +213,12 @@ dependencies = [ [[package]] name = "hbbytecode" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#784d552c1dee2a3cfde4b83e01523d91988bb554" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#a3355a59c0727e58519a94a8f65013beb9c2331b" [[package]] name = "hblang" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#784d552c1dee2a3cfde4b83e01523d91988bb554" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#a3355a59c0727e58519a94a8f65013beb9c2331b" dependencies = [ "hashbrown", "hbbytecode", @@ -229,7 +229,7 @@ dependencies = [ [[package]] name = "hbvm" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#784d552c1dee2a3cfde4b83e01523d91988bb554" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#a3355a59c0727e58519a94a8f65013beb9c2331b" dependencies = [ "hbbytecode", ] diff --git a/kernel/src/kmain.rs b/kernel/src/kmain.rs index fdd6700..a9f7bc6 100644 --- a/kernel/src/kmain.rs +++ b/kernel/src/kmain.rs @@ -76,6 +76,7 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! { "Graphics front ptr {:?}", fb1.address.as_ptr().unwrap() as *const u8 ); + log::info!("Started AbleOS"); unsafe { let executor = LazyCell::::force_mut(&mut EXECUTOR); @@ -132,7 +133,6 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! { executor.run(); }; - log::info!("Started AbleOS"); crate::arch::spin_loop() } diff --git a/sysdata/libraries/stn/src/hash/foldhash.hb b/sysdata/libraries/stn/src/hash/foldhash.hb new file mode 100644 index 0000000..2aa9e1b --- /dev/null +++ b/sysdata/libraries/stn/src/hash/foldhash.hb @@ -0,0 +1,189 @@ +/* +* This code is an implementation of the FoldHash algorithm from https://github.com/orlp/foldhash, +* originally written by Orson Peters under the zlib license. +* +* Changes to the original code were made to meet the simplicity requirements of this implementation. +* Behaviour aims to be equivalent but not identical to the original code. +* +* Copyright (c) 2024 Orson Peters +* +* This software is provided 'as-is', without any express or implied warranty. In +* no event will the authors be held liable for any damages arising from the use of +* this software. +* +* Permission is granted to anyone to use this software for any purpose, including +* commercial applications, and to alter it and redistribute it freely, subject to +* the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim +* that you wrote the original software. If you use this software in a product, +* an acknowledgment in the product documentation would be appreciated but is +* not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +*/; + +.{math, random} := @use("../lib.hb") + +$ARBITRARY0 := 0x243F6A8885A308D3 +$ARBITRARY1 := 0x13198A2E03707344 +$ARBITRARY2 := 0xA4093822299F31D0 +$ARBITRARY3 := 0x82EFA98EC4E6C89 +$ARBITRARY4 := 0x452821E638D01377 +$ARBITRARY5 := 0xBE5466CF34E90C6C +$ARBITRARY6 := 0xC0AC29B7C97C50DD +$ARBITRARY7 := 0x3F84D5B5B5470917 +$ARBITRARY8 := 0x9216D5D98979FB1B +$ARBITRARY9 := 0xD1310BA698DFB5AC +$FIXED_GLOBAL_SEED := [uint].(ARBITRARY4, ARBITRARY5, ARBITRARY6, ARBITRARY7) + +global_seed := 0 + +u128 := packed struct {a: uint, b: uint} + +$folded_multiply := fn(x: uint, y: uint): uint { + lx := @as(u32, @intcast(x)) + ly := @as(u32, @intcast(y)) + hx := x >> 32 + hy := y >> 32 + afull := lx * hy + bfull := hx * ly + return afull ^ (bfull << 32 | bfull >> 32) +} + +hash_bytes_medium := fn(bytes: ^u8, len: uint, s0: uint, s1: uint, fold_seed: uint): uint { + lo := bytes + end := bytes + len + hi := end - 16 + + loop if lo >= hi break else { + a := *@as(^uint, @bitcast(lo)) + b := *@as(^uint, @bitcast(lo + 8)) + c := *@as(^uint, @bitcast(hi)) + d := *@as(^uint, @bitcast(hi + 8)) + s0 = folded_multiply(a ^ s0, c ^ fold_seed) + s1 = folded_multiply(b ^ s1, d ^ fold_seed) + hi -= 16 + lo += 16 + } + return s0 ^ s1 +} + +hash_bytes_long := fn(bytes: ^u8, len: uint, s0: uint, s1: uint, s2: uint, s3: uint, fold_seed: uint): uint { + $chunk_size := 64 + chunks := len / chunk_size + remainder := len % chunk_size + + ptr := bytes + i := 0 + loop if i >= chunks break else { + a := *@as(^uint, @bitcast(ptr)) + b := *@as(^uint, @bitcast(ptr + 8)) + c := *@as(^uint, @bitcast(ptr + 16)) + d := *@as(^uint, @bitcast(ptr + 24)) + e := *@as(^uint, @bitcast(ptr + 32)) + f := *@as(^uint, @bitcast(ptr + 40)) + g := *@as(^uint, @bitcast(ptr + 48)) + h := *@as(^uint, @bitcast(ptr + 56)) + + s0 = folded_multiply(a ^ s0, e ^ fold_seed) + s1 = folded_multiply(b ^ s1, f ^ fold_seed) + s2 = folded_multiply(c ^ s2, g ^ fold_seed) + s3 = folded_multiply(d ^ s3, h ^ fold_seed) + + ptr += chunk_size + i += 1 + } + + s0 ^= s2 + s1 ^= s3 + + if remainder > 0 { + remainder_start := bytes + len - math.max(uint, remainder, 16) + return hash_bytes_medium(remainder_start, math.max(uint, remainder, 16), s0, s1, fold_seed) + } + + return s0 ^ s1 +} + +FoldHasher := struct { + accumulator: uint, + original_seed: uint, + sponge: u128, + sponge_len: u8, + fold_seed: uint, + expand_seed: uint, + expand_seed2: uint, + expand_seed3: uint, + + $new := fn(seed: uint): Self { + return .( + seed, + seed, + .(0, 0), + 0, + FIXED_GLOBAL_SEED[0], + FIXED_GLOBAL_SEED[1], + FIXED_GLOBAL_SEED[2], + FIXED_GLOBAL_SEED[3], + ) + } + + default := fn(): Self { + if global_seed == 0 { + // ! consider this "secure enough" for now + global_seed = random.any(uint) + } + return Self.new(global_seed) + } + + write := fn(self: ^Self, bytes: ^u8, len: uint): void { + s0 := self.accumulator + s1 := self.expand_seed + if len <= 16 { + if len >= 8 { + s0 ^= *@bitcast(bytes) + s1 ^= *@bitcast(bytes + len - 8) + } else if len >= 4 { + s0 ^= *@as(^u32, @bitcast(bytes)) + s1 ^= *@as(^u32, @bitcast(bytes + len - 4)) + } else if len > 0 { + lo := *bytes + mid := *(bytes + len / 2) + hi := *(bytes + len - 1) + s0 ^= lo + s1 ^= @as(uint, hi) << 8 | mid + } + self.accumulator = folded_multiply(s0, s1) + } else if len < 256 { + self.accumulator = hash_bytes_medium(bytes, len, s0, s1, self.fold_seed) + } else { + self.accumulator = hash_bytes_long( + bytes, + len, + s0, + s1, + self.expand_seed2, + self.expand_seed3, + self.fold_seed, + ) + } + } + + finish := fn(self: ^Self): uint { + if self.sponge_len > 0 { + return folded_multiply(self.sponge.b ^ self.accumulator, self.sponge.a ^ self.fold_seed) + } else { + return self.accumulator + } + } + + reset := fn(self: ^Self): void { + self.accumulator = self.original_seed + self.sponge = .(0, 0) + self.sponge_len = 0 + } +} \ No newline at end of file diff --git a/sysdata/libraries/stn/src/hash/lib.hb b/sysdata/libraries/stn/src/hash/lib.hb new file mode 100644 index 0000000..da97bfd --- /dev/null +++ b/sysdata/libraries/stn/src/hash/lib.hb @@ -0,0 +1,2 @@ +//! NON CRYPTOGRAPHIC HASHER +foldhash := @use("foldhash.hb") \ No newline at end of file diff --git a/sysdata/libraries/stn/src/lib.hb b/sysdata/libraries/stn/src/lib.hb index d90217b..dc6494e 100644 --- a/sysdata/libraries/stn/src/lib.hb +++ b/sysdata/libraries/stn/src/lib.hb @@ -1,5 +1,6 @@ acs := @use("acs.hb") allocators := @use("alloc/lib.hb") +hashers := @use("hash/lib.hb") string := @use("string.hb") log := @use("log.hb") memory := @use("memory.hb") diff --git a/sysdata/programs/hash_test/meta.toml b/sysdata/programs/hash_test/meta.toml new file mode 100644 index 0000000..fc157f1 --- /dev/null +++ b/sysdata/programs/hash_test/meta.toml @@ -0,0 +1,11 @@ +[package] +name = "hash_test" +authors = [""] + +[dependants.libraries] + +[dependants.binaries] +hblang.version = "1.0.0" + +[build] +command = "hblang src/main.hb" diff --git a/sysdata/programs/hash_test/src/main.hb b/sysdata/programs/hash_test/src/main.hb new file mode 100644 index 0000000..0840541 --- /dev/null +++ b/sysdata/programs/hash_test/src/main.hb @@ -0,0 +1,31 @@ +.{hashers, log, memory, string} := @use("../../../libraries/stn/src/lib.hb") + +main := fn(): void { + buffer := memory.request_page(1) + target := "abcdefghijklmnop\0" + strings := [^u8].("abcdefshijklmnop\0", "abcdefghijklnnop\0", "abcdefshijklmnop\0", "abcdefghijklmnop\0", "abcdefghijflmnop\0", "dbcdefghijklmnop\0", "abcdefghijklmnop\0") + len := @sizeof(@TypeOf(strings)) / @sizeof(^u8) + strlen := string.length(target) + + // hasher := hashers.foldhash.FoldHasher.new(1) + hasher := hashers.foldhash.FoldHasher.default() + hasher.write(target, strlen) + correct := hasher.finish() + + log.warn("target:\0") + log.warn(target) + + i := 0 + loop if i == len break else { + defer i += 1 + hasher.reset() + hasher.write(strings[i], strlen) + d := hasher.finish() + if d == correct { + log.warn("match found\0") + } + log.info(strings[i]) + log.debug(string.display_int(@bitcast(d), buffer, 16)) + string.clear(buffer) + } +} \ No newline at end of file diff --git a/sysdata/system_config.toml b/sysdata/system_config.toml index 61344f6..34b0649 100644 --- a/sysdata/system_config.toml +++ b/sysdata/system_config.toml @@ -46,5 +46,8 @@ resolution = "1024x768x24" # [boot.limine.ableos.modules.processes] # path = "boot:///processes.hbf" +# [boot.limine.ableos.modules.alloc_test] +# path = "boot:///alloc_test.hbf" + [boot.limine.ableos.modules.alloc_test] -path = "boot:///alloc_test.hbf" \ No newline at end of file +path = "boot:///hash_test.hbf"