aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXe Iaso <me@xeiaso.net>2025-04-13 18:50:29 -0400
committerXe Iaso <me@xeiaso.net>2025-04-13 18:50:29 -0400
commit72d6eda7de649edd4a3dfd61aa952967d5c36aa3 (patch)
tree5d14d481eec3b18cad7f0d01231fd479f5659bd3
parent33d31e03b08646f0c75522a353c762f204b45211 (diff)
downloadanubis-72d6eda7de649edd4a3dfd61aa952967d5c36aa3.tar.xz
anubis-72d6eda7de649edd4a3dfd61aa952967d5c36aa3.zip
enable simd128
Signed-off-by: Xe Iaso <me@xeiaso.net>
-rw-r--r--Cargo.lock56
-rw-r--r--Makefile10
-rw-r--r--go.mod11
-rw-r--r--go.sum12
-rw-r--r--package.json4
-rw-r--r--wasm/anubis/src/lib.rs1
-rw-r--r--wasm/pow/sha256/Cargo.toml2
-rw-r--r--wasm/wasm_test.go120
8 files changed, 143 insertions, 73 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ee8ad48..11d059f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -38,7 +38,7 @@ version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
dependencies = [
- "digest",
+ "digest 0.10.7",
]
[[package]]
@@ -51,12 +51,27 @@ dependencies = [
]
[[package]]
+name = "block-buffer"
+version = "0.11.0-rc.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a229bfd78e4827c91b9b95784f69492c1b77c1ab75a45a8a037b139215086f94"
+dependencies = [
+ "hybrid-array",
+]
+
+[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
+name = "const-oid"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0dabb6555f92fb9ee4140454eb5dcd14c7960e1225c6d1a6cc361f032947713e"
+
+[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -76,17 +91,37 @@ dependencies = [
]
[[package]]
+name = "crypto-common"
+version = "0.2.0-rc.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "170d71b5b14dec99db7739f6fc7d6ec2db80b78c3acb77db48392ccc3d8a9ea0"
+dependencies = [
+ "hybrid-array",
+]
+
+[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
- "block-buffer",
- "crypto-common",
+ "block-buffer 0.10.4",
+ "crypto-common 0.1.6",
"subtle",
]
[[package]]
+name = "digest"
+version = "0.11.0-pre.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c478574b20020306f98d61c8ca3322d762e1ff08117422ac6106438605ea516"
+dependencies = [
+ "block-buffer 0.11.0-rc.4",
+ "const-oid",
+ "crypto-common 0.2.0-rc.2",
+]
+
+[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -97,6 +132,15 @@ dependencies = [
]
[[package]]
+name = "hybrid-array"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4dab50e193aebe510fe0e40230145820e02f48dae0cf339ea4204e6e708ff7bd"
+dependencies = [
+ "typenum",
+]
+
+[[package]]
name = "libc"
version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -121,13 +165,13 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
[[package]]
name = "sha2"
-version = "0.10.8"
+version = "0.11.0-pre.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
+checksum = "19b4241d1a56954dce82cecda5c8e9c794eef6f53abe5e5216bac0a0ea71ffa7"
dependencies = [
"cfg-if",
"cpufeatures",
- "digest",
+ "digest 0.11.0-pre.10",
]
[[package]]
diff --git a/Makefile b/Makefile
index 9b8b61c..c4337e6 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,9 @@
NODE_MODULES = node_modules
VERSION := $(shell cat ./VERSION)
-.PHONY: build assets deps lint prebaked-build test
+export RUSTFLAGS=-Ctarget-feature=+simd128
+
+.PHONY: build assets deps lint prebaked-build test wasm
assets:
npm run assets
@@ -24,4 +26,8 @@ prebaked-build:
go build -o ./var/anubis -ldflags "-X 'github.com/TecharoHQ/anubis.Version=$(VERSION)'" ./cmd/anubis
test:
- npm run test \ No newline at end of file
+ npm run test
+
+wasm:
+ cargo build --release --target wasm32-unknown-unknown
+ cp -vf ./target/wasm32-unknown-unknown/release/*.wasm ./web/static/wasm \ No newline at end of file
diff --git a/go.mod b/go.mod
index 6641ceb..43009cf 100644
--- a/go.mod
+++ b/go.mod
@@ -11,12 +11,13 @@ require (
github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a
github.com/tetratelabs/wazero v1.9.0
github.com/yl2chen/cidranger v1.0.2
- golang.org/x/net v0.38.0
+ golang.org/x/net v0.39.0
)
require (
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e // indirect
+ github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794 // indirect
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
@@ -42,15 +43,17 @@ require (
github.com/prometheus/procfs v0.15.1 // indirect
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 // indirect
golang.org/x/mod v0.24.0 // indirect
- golang.org/x/sync v0.12.0 // indirect
- golang.org/x/sys v0.31.0 // indirect
- golang.org/x/tools v0.31.0 // indirect
+ golang.org/x/perf v0.0.0-20250408013232-71ba5bc8ccce // indirect
+ golang.org/x/sync v0.13.0 // indirect
+ golang.org/x/sys v0.32.0 // indirect
+ golang.org/x/tools v0.32.0 // indirect
google.golang.org/protobuf v1.36.4 // indirect
honnef.co/go/tools v0.6.1 // indirect
)
tool (
github.com/a-h/templ/cmd/templ
+ golang.org/x/perf/cmd/benchstat
golang.org/x/tools/cmd/stringer
honnef.co/go/tools/cmd/staticcheck
)
diff --git a/go.sum b/go.sum
index ad39bb5..277d165 100644
--- a/go.sum
+++ b/go.sum
@@ -4,6 +4,8 @@ github.com/a-h/parse v0.0.0-20250122154542-74294addb73e h1:HjVbSQHy+dnlS6C3XajZ6
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e/go.mod h1:3mnrkvGpurZ4ZrTDbYU84xhwXW2TjTKShSwjRi2ihfQ=
github.com/a-h/templ v0.3.857 h1:6EqcJuGZW4OL+2iZ3MD+NnIcG7nGkaQeF2Zq5kf9ZGg=
github.com/a-h/templ v0.3.857/go.mod h1:qhrhAkRFubE7khxLZHsBFHfX+gWwVNKbzKeF9GlPV4M=
+github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794 h1:xlwdaKcTNVW4PtpQb8aKA4Pjy0CdJHEqvFbAnvR5m2g=
+github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794/go.mod h1:7e+I0LQFUI9AXWxOfsQROs9xPhoJtbsyWcjJqDd4KPY=
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -96,11 +98,17 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
+golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
+golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
+golang.org/x/perf v0.0.0-20250408013232-71ba5bc8ccce h1:KAIyikguO7lID+oSo3Dnut9RawUS+RWK8Ejj9KPvwU4=
+golang.org/x/perf v0.0.0-20250408013232-71ba5bc8ccce/go.mod h1:tAdCL3nMN92yGFHY2TrzbGPP0q+LaOFewlib1WPJdpA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
+golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -113,6 +121,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
+golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -130,6 +140,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
+golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU=
+golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
diff --git a/package.json b/package.json
index c45a449..5ab30ab 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
"test": "npm run assets && go test ./...",
"test:integration": "npm run assets && go test -v ./internal/test",
"assets:frontend": "go generate ./... && ./web/build.sh && ./xess/build.sh",
- "assets:wasm": "cargo build --release --target wasm32-unknown-unknown && sh -c 'cp -vf ./target/wasm32-unknown-unknown/release/*.wasm ./web/static/wasm'",
+ "assets:wasm": "RUSTFLAGS='-C target-feature=+simd128' cargo build --release --target wasm32-unknown-unknown && sh -c 'cp -vf ./target/wasm32-unknown-unknown/release/*.wasm ./web/static/wasm'",
"assets": "npm run assets:frontend && npm run assets:wasm",
"build": "npm run assets && go build -o ./var/anubis ./cmd/anubis",
"dev": "npm run assets && go run ./cmd/anubis --use-remote-address",
@@ -24,4 +24,4 @@
"postcss-import-url": "^7.2.0",
"postcss-url": "^10.1.3"
}
-} \ No newline at end of file
+}
diff --git a/wasm/anubis/src/lib.rs b/wasm/anubis/src/lib.rs
index 2b16137..28994ec 100644
--- a/wasm/anubis/src/lib.rs
+++ b/wasm/anubis/src/lib.rs
@@ -1,4 +1,3 @@
-use std::boxed::Box;
use std::sync::{LazyLock, Mutex};
#[cfg(target_arch = "wasm32")]
diff --git a/wasm/pow/sha256/Cargo.toml b/wasm/pow/sha256/Cargo.toml
index 7e60576..a28309b 100644
--- a/wasm/pow/sha256/Cargo.toml
+++ b/wasm/pow/sha256/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2024"
crate-type = ["cdylib"]
[dependencies]
-sha2 = "0.10"
+sha2 = "0.11.0-pre.5"
anubis = { path = "../../anubis" }
diff --git a/wasm/wasm_test.go b/wasm/wasm_test.go
index 4caa0b6..b60e226 100644
--- a/wasm/wasm_test.go
+++ b/wasm/wasm_test.go
@@ -4,6 +4,7 @@ import (
"context"
"crypto/sha256"
"fmt"
+ "io/fs"
"os"
"testing"
"time"
@@ -11,10 +12,8 @@ import (
"github.com/TecharoHQ/anubis/web"
)
-func TestArgon2ID(t *testing.T) {
- const difficulty = 4 // one nibble, intentionally easy for testing
-
- fin, err := web.Static.Open("static/wasm/argon2id.wasm")
+func abiTest(t *testing.T, fname string, difficulty uint32) {
+ fin, err := web.Static.Open("static/wasm/" + fname)
if err != nil {
t.Fatal(err)
}
@@ -22,7 +21,7 @@ func TestArgon2ID(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
t.Cleanup(cancel)
- runner, err := NewRunner(ctx, "argon2id.wasm", fin)
+ runner, err := NewRunner(ctx, fname, fin)
if err != nil {
t.Fatal(err)
}
@@ -67,65 +66,46 @@ func TestArgon2ID(t *testing.T) {
t.Logf("used %d pages of wasm memory (%d bytes)", runner.module.Memory().Size()/63356, runner.module.Memory().Size())
}
-func TestSHA256(t *testing.T) {
- const difficulty = 4 // one nibble, intentionally easy for testing
-
- fin, err := web.Static.Open("static/wasm/sha256.wasm")
+func TestAlgos(t *testing.T) {
+ fnames, err := fs.ReadDir(web.Static, "static/wasm")
if err != nil {
t.Fatal(err)
}
+
+ for _, fname := range fnames {
+ fname := fname
+ t.Run(fname.Name(), func(t *testing.T) {
+ abiTest(t, fname.Name(), 4)
+ })
+ }
+}
+
+func bench(b *testing.B, fname string, difficulties []uint32) {
+ fin, err := web.Static.Open("static/wasm/" + fname)
+ if err != nil {
+ b.Fatal(err)
+ }
defer fin.Close()
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
- t.Cleanup(cancel)
+ b.Cleanup(cancel)
- runner, err := NewRunner(ctx, "sha256.wasm", fin)
+ runner, err := NewRunner(ctx, fname, fin)
if err != nil {
- t.Fatal(err)
+ b.Fatal(err)
}
h := sha256.New()
- fmt.Fprint(h, t.Name())
+ fmt.Fprint(h, "This is an example value that exists only to test the system.")
data := h.Sum(nil)
if n, err := runner.WriteData(ctx, data); err != nil {
- t.Fatalf("can't write data: %v", err)
+ b.Fatalf("can't write data: %v", err)
} else {
- t.Logf("wrote %d bytes to data segment", n)
- }
-
- t0 := time.Now()
- nonce, err := runner.anubisWork(ctx, difficulty, 0, 1)
- if err != nil {
- t.Fatalf("can't do test work run: %v", err)
- }
- t.Logf("got nonce %d in %s", nonce, time.Since(t0))
-
- hash, err := runner.ReadResult(ctx)
- if err != nil {
- t.Fatalf("can't read result: %v", err)
- }
-
- t.Logf("got hash %x", hash)
-
- if err := runner.WriteVerification(ctx, hash); err != nil {
- t.Fatalf("can't write verification: %v", err)
- }
-
- ok, err := runner.anubisValidate(ctx, nonce, difficulty)
- if err != nil {
- t.Fatalf("can't run validation: %v", err)
- }
-
- if !ok {
- t.Error("validation failed")
+ b.Logf("wrote %d bytes to data segment", n)
}
-
- t.Logf("used %d pages of wasm memory (%d bytes)", runner.module.Memory().Size()/63356, runner.module.Memory().Size())
}
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)
@@ -140,7 +120,7 @@ func BenchmarkSHA256(b *testing.B) {
}
h := sha256.New()
- fmt.Fprint(h, os.Args[0])
+ fmt.Fprint(h, "testificate")
data := h.Sum(nil)
if n, err := runner.WriteData(ctx, data); err != nil {
@@ -149,11 +129,26 @@ func BenchmarkSHA256(b *testing.B) {
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)
- }
+ for _, cs := range []struct {
+ Difficulty uint32
+ }{
+ {4},
+ {6},
+ {8},
+ {10},
+ {12},
+ {14},
+ {16},
+ } {
+ b.Run(fmt.Sprintf("difficulty/%d", cs.Difficulty), func(b *testing.B) {
+ for b.Loop() {
+ difficulty := cs.Difficulty
+ _, err := runner.anubisWork(ctx, difficulty, 0, 1)
+ if err != nil {
+ b.Fatalf("can't do test work run: %v", err)
+ }
+ }
+ })
}
}
@@ -183,10 +178,21 @@ func BenchmarkArgon2ID(b *testing.B) {
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)
- }
+ for _, cs := range []struct {
+ Difficulty uint32
+ }{
+ {4},
+ {6},
+ {8},
+ } {
+ b.Run(fmt.Sprintf("difficulty/%d", cs.Difficulty), func(b *testing.B) {
+ for b.Loop() {
+ difficulty := cs.Difficulty
+ _, err := runner.anubisWork(ctx, difficulty, 0, 1)
+ if err != nil {
+ b.Fatalf("can't do test work run: %v", err)
+ }
+ }
+ })
}
}