diff --git a/Cargo.lock b/Cargo.lock index 57bdde7b..30043153 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,12 +56,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "libc" version = "0.2.171" @@ -83,7 +77,6 @@ dependencies = [ name = "sha256" version = "0.1.0" dependencies = [ - "lazy_static", "sha2", ] diff --git a/wasm/pow/sha256/Cargo.toml b/wasm/pow/sha256/Cargo.toml index c2bf025b..35a12f3f 100644 --- a/wasm/pow/sha256/Cargo.toml +++ b/wasm/pow/sha256/Cargo.toml @@ -7,7 +7,6 @@ edition = "2024" crate-type = ["cdylib"] [dependencies] -lazy_static = "1.5" sha2 = "0.10" [lints.clippy] diff --git a/wasm/pow/sha256/src/lib.rs b/wasm/pow/sha256/src/lib.rs index 8179bf35..5c9002b7 100644 --- a/wasm/pow/sha256/src/lib.rs +++ b/wasm/pow/sha256/src/lib.rs @@ -1,28 +1,29 @@ -use lazy_static::lazy_static; use sha2::{Digest, Sha256}; -use std::sync::Mutex; +use std::sync::{Arc, LazyLock, Mutex}; -// Statically allocated buffers at compile time. -lazy_static! { - /// The data buffer is a bit weird in that it doesn't have an explicit length as it can - /// and will change depending on the challenge input that was sent by the server. - /// However, it can only fit 4096 bytes of data (one amd64 machine page). This is - /// slightly overkill for the purposes of an Anubis check, but it's fine to assume - /// that the browser can afford this much ram usage. - /// - /// Callers should fetch the base data pointer, write up to 4096 bytes, and then - /// `set_data_length` the number of bytes they have written - /// - /// This is also functionally a write-only buffer, so it doesn't really matter that - /// the length of this buffer isn't exposed. - static ref DATA_BUFFER: Mutex<[u8; 4096]> = Mutex::new([0; 4096]); - static ref DATA_LENGTH: Mutex = Mutex::new(0); +/// The data buffer is a bit weird in that it doesn't have an explicit length as it can +/// and will change depending on the challenge input that was sent by the server. +/// However, it can only fit 4096 bytes of data (one amd64 machine page). This is +/// slightly overkill for the purposes of an Anubis check, but it's fine to assume +/// that the browser can afford this much ram usage. +/// +/// Callers should fetch the base data pointer, write up to 4096 bytes, and then +/// `set_data_length` the number of bytes they have written +/// +/// This is also functionally a write-only buffer, so it doesn't really matter that +/// the length of this buffer isn't exposed. +static DATA_BUFFER: LazyLock>> = + LazyLock::new(|| Arc::new(Mutex::new([0; 4096]))); - /// SHA-256 hashes are 32 bytes (256 bits). These are stored in static buffers due to the - /// fact that you cannot easily pass data from host space to WebAssembly space. - static ref RESULT_HASH: Mutex<[u8; 32]> = Mutex::new([0; 32]); - static ref VERIFICATION_HASH: Mutex<[u8; 32]> = Mutex::new([0; 32]); -} +static DATA_LENGTH: LazyLock> = LazyLock::new(|| Mutex::new(0)); + +/// SHA-256 hashes are 32 bytes (256 bits). These are stored in static buffers due to the +/// fact that you cannot easily pass data from host space to WebAssembly space. +static RESULT_HASH: LazyLock>> = + LazyLock::new(|| Arc::new(Mutex::new([0; 32]))); + +static VERIFICATION_HASH: LazyLock>> = + LazyLock::new(|| Arc::new(Mutex::new([0; 32]))); #[link(wasm_import_module = "anubis")] unsafe extern "C" { diff --git a/wasm/wasm.go b/wasm/wasm.go index 8f1aeb23..4f21aac2 100644 --- a/wasm/wasm.go +++ b/wasm/wasm.go @@ -111,6 +111,8 @@ func (r *Runner) dataPtr(ctx context.Context) (uint32, error) { return 0, err } + fmt.Printf("data pointer: 0x%x\n", results[0]) + return uint32(results[0]), nil } diff --git a/wasm/wasm_test.go b/wasm/wasm_test.go index 3b04f065..c64dc7c9 100644 --- a/wasm/wasm_test.go +++ b/wasm/wasm_test.go @@ -64,3 +64,37 @@ func TestSHA256(t *testing.T) { t.Error("validation failed") } } + +func BenchmarkSHA256(b *testing.B) { + const difficulty = 4 // one nibble, intentionally easy for testing + + fin, err := web.Static.Open("static/wasm/sha256.wasm") + if err != nil { + b.Fatal(err) + } + defer fin.Close() + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + b.Cleanup(cancel) + + runner, err := NewRunner(ctx, "sha256.wasm", fin) + if err != nil { + b.Fatal(err) + } + + h := sha256.New() + fmt.Fprint(h, os.Args[0]) + data := h.Sum(nil) + + if n, err := runner.WriteData(ctx, data); err != nil { + b.Fatalf("can't write data: %v", err) + } else { + b.Logf("wrote %d bytes to data segment", n) + } + + for b.Loop() { + _, err := runner.anubisWork(ctx, difficulty, 0, 1) + if err != nil { + b.Fatalf("can't do test work run: %v", err) + } + } +}