wasm: add benchmark, rip out lazy_static

Signed-off-by: Xe Iaso <me@xeiaso.net>
This commit is contained in:
Xe Iaso
2025-04-09 19:35:45 -04:00
parent f728779c08
commit d0d49a4d3c
5 changed files with 59 additions and 30 deletions

7
Cargo.lock generated
View File

@@ -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",
]

View File

@@ -7,7 +7,6 @@ edition = "2024"
crate-type = ["cdylib"]
[dependencies]
lazy_static = "1.5"
sha2 = "0.10"
[lints.clippy]

View File

@@ -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<usize> = 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<Arc<Mutex<[u8; 4096]>>> =
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<Mutex<usize>> = 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<Arc<Mutex<[u8; 32]>>> =
LazyLock::new(|| Arc::new(Mutex::new([0; 32])));
static VERIFICATION_HASH: LazyLock<Arc<Mutex<[u8; 32]>>> =
LazyLock::new(|| Arc::new(Mutex::new([0; 32])));
#[link(wasm_import_module = "anubis")]
unsafe extern "C" {

View File

@@ -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
}

View File

@@ -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)
}
}
}