{"_id":"@btx-tools/matmul-wasm","_rev":"3-bd20a958df4041d54ec747496491ca94","name":"@btx-tools/matmul-wasm","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@btx-tools/matmul-wasm","version":"0.1.0","keywords":["btx","matmul","m31","wasm","captcha"],"license":"MIT OR Apache-2.0","_id":"@btx-tools/matmul-wasm@0.1.0","maintainers":[{"name":"visitor-code","email":"visitor@friction.market"}],"homepage":"https://github.com/btx-tools/btx-challenges-wasm#readme","bugs":{"url":"https://github.com/btx-tools/btx-challenges-wasm/issues"},"dist":{"shasum":"e22cfa19211b4f9d23fbfb8fe51e19eae745c4a7","tarball":"https://registry.npmjs.org/@btx-tools/matmul-wasm/-/matmul-wasm-0.1.0.tgz","fileCount":7,"integrity":"sha512-qVXpmzxKYl0VvamFwgvSvnjhNcwgOfcG5cE4r/StLifbuHBTQTVPTSorOQeRxeGY6r25w3jIlXtGHoCm5Mfm4g==","signatures":[{"sig":"MEQCIHiWpzOND+wFa6NqLYN6CNVuzq7Zg9QQuUI4aCrdqzuEAiAo/aNZG29J/Vo72SYhdrgKpD7FUcasI1vCLWi6OJCNPw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":84568},"main":"btx_challenges_wasm.js","type":"module","types":"btx_challenges_wasm.d.ts","gitHead":"a269b34968ed032a306bda114c2f6c108d0b4cde","_npmUser":{"name":"visitor-code","email":"visitor@friction.market"},"repository":{"url":"git+https://github.com/btx-tools/btx-challenges-wasm.git","type":"git"},"_npmVersion":"10.9.3","description":"WASM matmul solver kernel for @btx-tools/challenges-sdk — byte-exact port of btxd's matmul service-challenge PoW","directories":{},"sideEffects":["./snippets/*"],"_nodeVersion":"22.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/matmul-wasm_0.1.0_1779571769434_0.07882020489400654","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@btx-tools/matmul-wasm","version":"0.1.1","keywords":["btx","matmul","m31","wasm","captcha"],"license":"MIT OR Apache-2.0","_id":"@btx-tools/matmul-wasm@0.1.1","maintainers":[{"name":"visitor-code","email":"visitor@friction.market"}],"homepage":"https://github.com/btx-tools/btx-challenges-wasm#readme","bugs":{"url":"https://github.com/btx-tools/btx-challenges-wasm/issues"},"dist":{"shasum":"843c92d1858e2e31c9e87d5d988218ca51bc3976","tarball":"https://registry.npmjs.org/@btx-tools/matmul-wasm/-/matmul-wasm-0.1.1.tgz","fileCount":7,"integrity":"sha512-n4FxC8ae6vJyIgIjbN0tybf8qxwIxHTTI5p91MGpYyMh9mVICyyegmZIya6OCzdAWWNS6DMvZw15RnYSnqtwww==","signatures":[{"sig":"MEQCIA2Mwn+HwQuNLNwH86EUHVvvTUMB1t8LdNwIzOmqGtYUAiBvLdCJZu/lDdikFD4y5aVPG6CIE8adC0D7JOd8zQi/aQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":84576},"main":"btx_challenges_wasm.js","type":"module","types":"btx_challenges_wasm.d.ts","gitHead":"775970cc5833fa37ad719aee64db8f14206d4c59","_npmUser":{"name":"visitor-code","email":"visitor@friction.market"},"repository":{"url":"git+https://github.com/btx-tools/btx-challenges-wasm.git","type":"git"},"_npmVersion":"10.9.3","description":"WASM matmul solver kernel for @btx-tools/challenges-sdk — byte-exact port of btxd's matmul service-challenge PoW","directories":{},"sideEffects":["./snippets/*"],"_nodeVersion":"22.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/matmul-wasm_0.1.1_1779615632617_0.5798983854372901","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@btx-tools/matmul-wasm","type":"module","description":"WASM matmul solver kernel for @btx-tools/challenges-sdk — byte-exact port of btxd's matmul service-challenge PoW","version":"0.1.2","license":"MIT OR Apache-2.0","repository":{"type":"git","url":"git+https://github.com/btx-tools/btx-challenges-wasm.git"},"main":"btx_challenges_wasm.js","types":"btx_challenges_wasm.d.ts","sideEffects":["./snippets/*"],"keywords":["btx","matmul","m31","wasm","captcha"],"_id":"@btx-tools/matmul-wasm@0.1.2","gitHead":"4dba94bc896f99893169ea60011eb7e449cda75e","bugs":{"url":"https://github.com/btx-tools/btx-challenges-wasm/issues"},"homepage":"https://github.com/btx-tools/btx-challenges-wasm#readme","_nodeVersion":"22.20.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-nMI2M610vzluRK6C0viMZEIslSXSi9uTFuvZVRr3T++mAQ+aDobC9Ga5Suj5Ji5sWCzVwnQW6uTiYBFr2soSmg==","shasum":"d6795940d46bff1f0ec36ce4ee60b548e23df416","tarball":"https://registry.npmjs.org/@btx-tools/matmul-wasm/-/matmul-wasm-0.1.2.tgz","fileCount":7,"unpackedSize":85173,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIE4OuuMunE5wTAY5DtRp3pshA5pE8Es8LgOsEo7oZLbrAiB5GX/Vtxt++RMnnCMx1TqU3lIXUxhQwiZXS1MBz1uDVg=="}]},"_npmUser":{"name":"visitor-code","email":"visitor@friction.market"},"directories":{},"maintainers":[{"name":"visitor-code","email":"visitor@friction.market"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/matmul-wasm_0.1.2_1779624814957_0.07981926698244268"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-23T21:29:29.307Z","modified":"2026-05-24T12:13:35.277Z","0.1.0":"2026-05-23T21:29:29.622Z","0.1.1":"2026-05-24T09:40:32.738Z","0.1.2":"2026-05-24T12:13:35.165Z"},"bugs":{"url":"https://github.com/btx-tools/btx-challenges-wasm/issues"},"license":"MIT OR Apache-2.0","homepage":"https://github.com/btx-tools/btx-challenges-wasm#readme","keywords":["btx","matmul","m31","wasm","captcha"],"repository":{"type":"git","url":"git+https://github.com/btx-tools/btx-challenges-wasm.git"},"description":"WASM matmul solver kernel for @btx-tools/challenges-sdk — byte-exact port of btxd's matmul service-challenge PoW","maintainers":[{"name":"visitor-code","email":"visitor@friction.market"}],"readme":"# @btx-tools/matmul-wasm\n\nA **WASM matmul solver for BTX service challenges** — a byte-exact Rust→WASM port\nof btxd's matmul service-challenge proof-of-work. It produces a `(nonce, digest)`\nproof that btxd will accept on redemption, without a local node.\n\n> **Read the perf truth first.** This is the **fastest JS-environment solver** for\n> BTX challenges (~24× a pure-JS BigInt implementation) — genuinely useful on\n> **server / Node / edge / Deno / Bun / Workers**. It is **not** a drop-in casual\n> browser captcha: at the live block-mining difficulty (`n=512`) a full solve is\n> **~16 s on an 8-worker browser pool**, because the difficulty is calibrated to\n> the chain's fast *native* solver and a browser is ~100× slower per attempt.\n> See [Performance](#performance) for the numbers and [When to use it](#when-to-use-it)\n> for where that 16 s is and isn't acceptable.\n\nPart of the [`@btx-tools`](https://github.com/btx-tools) BTX admission toolkit,\nalongside [`@btx-tools/challenges-sdk`](https://github.com/btx-tools/btx-challenges-sdk).\n\n## What it is\n\nbtxd's matmul PoW: per nonce, derive a sigma from the block header, generate a\nlow-rank noise perturbation of two seed matrices `A, B`, run a canonical blocked\nmatrix multiply over the Mersenne-31 field (`q = 2³¹−1`), hash the transcript,\nand accept if `digest ≤ target`. This crate ports that hot loop to Rust and\ncompiles it to WebAssembly via `wasm-bindgen`.\n\n**Correctness is the whole point.** The output is validated **byte-exact** three\nindependent ways: against btxd's own pinned golden vectors, against the pure-JS\nreference (`@btx-tools/challenges-sdk`'s `solveJs`), and in a real browser worker.\nA wrong proof is worthless, so the port is pinned to byte-equality, not \"close\nenough.\"\n\n## Performance\n\nPer-attempt cost at the live production params (`n=512, b=16, r=8`), scalar WASM\n(no SIMD):\n\n| engine | per-attempt | source |\n|---|---|---|\n| V8 (Node, Apple silicon) | **128 ms** | `pkg-node` micro-bench |\n| SpiderMonkey (Firefox) | **165 ms** | in-browser bench |\n\nCost scales ~`n³` (measured, Node): `n=512 → 128 ms`, `n=256 → 15 ms` (fixed\nper-attempt overhead makes small-`n` deviate from a clean cubic).\n\n8-worker browser pool (`hardwareConcurrency=8`) ≈ 48 attempts/s, so at floor\ndifficulty (~770 attempts) a full solve is **~16 s**. Artifact size: **~51 KB**\n(`wasm-opt -Oz --enable-bulk-memory`).\n\n**Why not just turn on SIMD?** A 2–4× SIMD win doesn't bridge the ~100×\nbrowser-vs-native gap at `n=512` (~4–8 s at floor — still not a casual captcha).\nAnd `n` is policy-fixed by the chain (issued = 512; the issue RPC controls only\ndifficulty/time, not `n`), so an issuer cannot request a browser-friendly smaller\nmatrix. A full-strength, fast, no-node *browser* captcha needs an upstream\nbrowser-friendly proof primitive — that's a BTX-protocol question, not something\nthis crate can close. The full measurement write-up is the public evidence for\nthat ask.\n\n## When to use it\n\n✅ **A fast server / Node / edge solver** — solve on a caller's behalf in a\ntwo-tier deploy, or anywhere running without a local btxd. ~24× the pure-JS path.\n\n✅ **A deliberate high-friction gate** — account creation / KYC-alternative, where\na one-time ~16 s solve is *intended* friction (not a per-request captcha).\n\n✅ **The foundation** for any future smaller-`n` or upstream browser-friendly\nprimitive — the kernel is done and validated.\n\n❌ **A casual per-request browser captcha at `n=512`** — 16 s ≠ a captcha. Don't.\n\n## API\n\n```ts\nimport init, { WasmSolver } from '@btx-tools/matmul-wasm';        // web target\n// const { WasmSolver } = require('@btx-tools/matmul-wasm');       // nodejs target\n\nawait init(); // web only; nodejs target loads synchronously\n\nconst solver = new WasmSolver(\n  version, prevhash, merkleroot, time, bits,   // header fields (hex/uint)\n  n, b, r,                                       // matmul params\n  seedA, seedB, target,                          // BE-display hex (64 chars)\n);\n\n// Try `maxTries` nonces from `start`, stepping by `stride`. Returns\n// undefined if none found in this chunk. For an N-worker pool, worker k runs\n// solve_chunk(BigInt(k), BigInt(N), chunk) and the first to return wins.\nconst sol = solver.solve_chunk(0n, 1n, 1_000_000n);\nif (sol) {\n  sol.nonce_hex;   // 16-char hex\n  sol.digest_hex;  // BE-display hex (what btxd's redeem expects)\n}\n```\n\n`WasmSolver` validates the challenge once in its constructor (throws a catchable\n`JsError` on malformed input); `solve_chunk` is then panic-free, so a worker's\nloop never produces an opaque WASM trap.\n\n## Build from source\n\n```bash\nwasm-pack build --target web    --release --out-dir pkg        # browser ESM\nwasm-pack build --target nodejs --release --out-dir pkg-node   # Node CommonJS\n# or, to produce a scoped npm artifact for both targets:\n./scripts/build-npm.sh\n```\n\nRequires the Rust toolchain + `wasm-pack`. `wasm-opt -Oz --enable-bulk-memory`\nruns automatically (the `--enable-bulk-memory` flag is mandatory — rustc emits\n`memory.copy`/`memory.fill`).\n\n```bash\ncargo test                                  # 24 byte-exact + edge tests\ncargo clippy --all-targets -- -D warnings\n```\n\n## License\n\nDual-licensed under either [MIT](./LICENSE-MIT) or [Apache-2.0](./LICENSE-APACHE)\nat your option.\n","readmeFilename":"README.md"}