Skip to main content

Crate pow_buster

Crate pow_buster 

Source
Expand description

§PoW Buster

§Table of Contents

A fast, data-parallel, adversarially 1 implemented mCaptcha/Anubis/Cerberus/go-away/Cap.js PoW solver, targeting AVX-512/SHA-NI/simd128. Can be used for computing solutions to these systems without disabling privacy-enhancing features, without wasting energy in the browser.

The benchmarks demonstrate a significant performance gap between browser-based JavaScript execution and native implementations, suggesting fundamental challenges for PoW-based browser CAPTCHA systems.

Public web demo running on Netcup (R) RS 2000 G12, 8vCPU server at MSRP 14.58EUR/month. Ballparking 80-100MH/s/thread for SHA-2 and 170MH/s/thread for BLAKE3.

§Motivation / Why?

See MOTIVATION.md for more details.

A longer blabbing post regarding this

§Features

  • SHA-2 and BLAKE3 hotstarting with round-level precomputation granularity
  • Structure of Array hashing backed by register-resident SIMD.
  • 3 searching modes: Prefix greater than (mCaptcha), prefix less than (Anubis/go-away), mask test (Cerberus/Cap.js)
  • Greedy padding logic with 64-bit integer and floating point nonce stretching
  • Efficient outer loop and SIMD nonce encoding
  • Fully unrolled and monomorphic core friendly to pipelining and ternary logic instruction lowering
  • Short-circuiting comparison with $H_1 \to H_7$ feed-forward elision with optional 64-bit support
  • Switch to octal nonces when success rate is overwhelming
  • Fuzzy Anubis challenge handling
  • An API compatible with anubis_offload but doesn’t need a GPU to run.

§Building

MSRV: Rust 1.89+.

Requires AVX-512 (cpuid: avx512f) or SHA-NI+SSE4.1 (cpuid: sha, sse4_1) CPU or SIMD128 on WASM. If you don’t have any of these advanced instruction support, sorry, some “solutions” have “changed the way” of “security” (by paying with energy and battery life and making browsing on budget hardware hard). There is a pure Rust scalar fallback that should make the code compile and work regardless.

Recommended CPU feature flags in order of preference (Tagged releases will have Linux musl builds):

  • -Ctarget-cpu=native
  • -Ctarget-feature=+avx512vbmi (Artifacts released on top of x86-64-v4)
  • -Ctarget-feature=+avx512f (Artifacts released on top of x86-64-v3)
  • -Ctarget-cpu=x86-64-v2 (Will auto dispatch to accelerated solvers at runtime)
RUSTFLAGS="-Ctarget-cpu=x86-64-v2" cargo build --release --features cli

Optional Features:

  • compare-64bit: Compare 64-bit words instead of 32-bit words at ~5% penalty, almost never needed for realistic challenges. Not compatible with WASM.
  • client: End-to-end solver client, required for most non-computational functionality.
  • live-throughput-test: End-to-end multi-worker throughput benchmark.
  • server: Solver-as-a-Service API.
  • server-wasm: Solver-as-a-Service API (with WASM simd128 solver, build first with ./build_wasm.sh).
  • tracing: Write tracing for debugging.
  • tracing-subscriber: For binary releases only, writes tracing logs to console.

§Usage

§Using the CLI Solver

The most common use case is you have a non browser client (for example a CLI downloader, feed checker or other automation tool) and you want a valid token. pow-buster features comprehensive coverage for Anubis challenge workflow and basic coverage for Cerberus and go-away for your edge case non-JavaScript use cases.

> target/release/pow-buster anubis --url https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/diff/ 2>/dev/null

cookie: techaro.lol-anubis-auth=eyJeyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.ey<...>
§Custom User Agent

The default user agent is “pow-buster/x.x.x (NotAMozilla)”. Some adopters may hard block the default user agent or reject any non browser-like UAs, but regardless it is good etiquette to identify yourself using your actual bot name not just “pow-buster”. I personally think it is okay to “impersonate” a browser if the overblocking ruleset make it impossible to be “honest”, but you are responsible for your own actions.

For example TLNET blocks all UAs that do not start with “Mozilla”, we can make a compromise and put the magic word in the front and then disclose our actual UA responsibly as a workaround:

> target/release/pow-buster anubis --url https://texlive.info/tlnet-archive/
  2025-11-10T08:03:13.766683Z  WARN pow_buster::client: no challenge found
    at src/client.rs:510
    in pow_buster::client::solve_anubis_ex with base_url: "https://texlive.info/tlnet-archive/"

> USER_AGENT="Mozilla/5.0 MyDocumentationBot/0.1.0" target/release/
pow-buster anubis --url https://texlive.info/tlnet-archive/
  2025-11-10T08:39:40.397760Z  INFO pow_buster::client: Anubis cryptographic challenge, algorithm: "fast", estimated_workload: 1048576
    at src/client.rs:573
    in pow_buster::client::solve_anubis_ex with base_url: "https://texlive.info/tlnet-archive/"

  2025-11-10T08:39:40.418282Z  INFO pow_buster::client: solver finished, nonce: 1000000000081456411, attempted_nonces: 1879040
    at src/client.rs:591
    in pow_buster::client::solve_anubis_ex with base_url: "https://texlive.info/tlnet-archive/"

cookie: techaro.lol-anubis-auth=eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.ey<...>

§Using the browser extension

Browser addons will be released unsigned for reasons below. To install it you have to:

  • Get it signed under your developer account, or
  • On any Firefox browser that is not the release flavor (e.g. Nightly, LibreWolf, etc.), manually flip xpinstall.signatures.required to false in about:config to install them.

For easier to use (but less reliable) alternatives, I highly recommend trying out the NoPoW extension (which is signed by Mozilla because it is just a UA changer), main differences:

  • ✅ Works on non-default or challenge-all config.
  • ✅ Resistant to adopters who like to block specific request signatures because there is no request signature - vanilla vendor submission code is used.
  • ✅ Does not try to circumvent any administrative rules, code is law.
  • ❌ Will still “waste” CPU cycles, just (much) more efficiently.
  • ❌ The extension may violate Firefox Submission Guideline of being “self contained”. Although it can (and by default does) work without any server-side components, you have the option to use the preferences page to have it connect to a native pow-buster server and execute solution scripts generated by the server. This is to simplify my workflow of just having one server-side integration and increase agility of getting native acceleration from manual devTools based workflows to fully automated ones.

§Limitations

We assume you have a relatively modern and powerful platform, specifically:

  • A cold optimized build with end-to-end features may take up to 5 minutes as this program aggressively generates specialized kernels and build time isn’t my priority.
  • For Anubis target, this assumes the server is 64-bit (i.e. is able to accept a signed 64-bit nonce).
  • AVX-512 build requires Rust 1.89 or later.
  • All solvers are single-threaded and are intended to be scaled up using multiple workers optionally pinned to specific cores.
  • This is designed for “low”, practical-for-a-website difficulty settings, A worst-case $1 - P_{geom}(80e7, 1/\text{difficulty})$ chance of failure for any particular messaeg offset with most offset cases almost guaranteed to succeed eventually, which for 1e8 (takes about 10 seconds on a browser for mCaptcha and an eternity for Anubis) is about 0.03%. Go-away solver explores the full solution space and guarantees a solution if one exists.

§Ethical Disclaimer (i.e. the “How Dare you Publish this?” question)

This isn’t a vulnerability nor anything previously unknown, it’s a structural weakness that needs to be assessed. I didn’t “skip” or somehow “simplify” any number of SHA-2 rounds, it is a materialized analysis of performance characteristics of the system.

This is a structural limitation, PoW is supposed for global consensus, not maintaining a meaningful peer-to-peer “fair” hash rate margin, especially not when compared to commodity hardware. Every academic paper will tell you that PoW system loses protection margin using hardware or software optimizations. I implemented it, that’s it.

Website operators deploying a PoW system bear the responsibility to understand the performance characteristics and security implications of their chosen PoW parameters, and whether that protects against their identified threat. The purpose of this research is to provide the statistical analysis and empirical validation data necessary for informed deployment decisions, including optimized CPU only solutions.

§Benchmark

Most of the formal comparison is done against mCaptcha, because they have a WASM solver and cannot be immediately dismissed as “that’s JS overhead”/“we will do better later”.

TLDR; My extrapolated throughput for each approach, corroborated by empirical and formal benchmarks:

Extrapolated throughput

§Formal Benchmark (mCaptcha only)

Speedup against official solution, reported by Criterion.rs, single-threaded except for “mCaptcha User Survey extrapolated” column which uses all worker threads on the user’s browser:

Results on AMD Ryzen 9 7950X, 32 hyperthreads, when supported, single-hash number comes first (there is 90% chance your deployment is single-hash, this vagueness is IMO design oversight by the mCaptcha team), double-hash number comes second, all numbers are in milliseconds, compiled with -Ctarget-cpu=native unless otherwise specified.

DFactor (equiv. Anubis difficulty)AVX-512AVX-512 (32-byte salt)Safe Optimized (+) 2mCaptcha (+)mCaptcha Generic x64 (+)mCaptcha User Survey extrapolated 3
50_000 (3.90)0.554/0.9530.4871.5652.851/4.0095.600/9.53714.556
100_000 (4.15)1.105/1.9030.9783.1725.698/7.81711.152/18.57529.11176
1_000_000 (4.98)11.138/18.5159.70731.62254.931/80.029117.34/188.41291.118
4_000_000 (5.48)46.136/75.63037.475125.06222.93/323.70432.81/777.881164.471
10_000_000 (5.81)107.49/186.0194.645323.06564.41/805.02DNS2911.18

(+) = SNA-NI and a standard SHA-256 implementation is used.

§End to End Benchmark

A default official docker-compose instance is used for the benchmark target (the default 33-byte salt was unchanged).

§CPU only

The following were configured for difficulty 5_000_000 (default max tier).

10 consecutive solutions using the official Captcha widget: [0.105s, 1.69s, 1.06s, 1.89s, 1.91s, 1.09s, 1.80s, 0.97s, 0.71s, 1.15s, 3.59s, 1.09s, 0.14s, 3.98s, 1.26s, 1.05s, 1.26s]

> RUSTFLAGS="-Ctarget-cpu=native" \
    cargo run --features cli --release -- live \
    --site-key emPgsyJP5SWeNEot2IBbg0ezOE1GNhof \
    --n-workers 38 \
    --do-control >/dev/null

You are hitting host http://localhost:7000
running 10 seconds of control sending random proofs
[0.0s] succeeded: 0, failed: 0, 5s: 0.0rps, 5s_failed: 0.0rps
[5.0s] succeeded: 725, failed: 0, 5s: 145.0rps, 5s_failed: 0.0rps
[10.0s] succeeded: 1453, failed: 0, 5s: 145.6rps, 5s_failed: 0.0rps
Fake Proof Control: 3732 requests in 10.1 seconds, 369.2 rps
[15.0s] succeeded: 2690, failed: 0, 5s: 247.4rps, 5s_failed: 0.0rps
[20.0s] succeeded: 3902, failed: 0, 5s: 242.4rps, 5s_failed: 0.0rps
[25.0s] succeeded: 5110, failed: 0, 5s: 241.6rps, 5s_failed: 0.0rps
[30.0s] succeeded: 6368, failed: 0, 5s: 251.6rps, 5s_failed: 0.0rps
[35.0s] succeeded: 7587, failed: 0, 5s: 243.8rps, 5s_failed: 0.0rps
[40.0s] succeeded: 8840, failed: 0, 5s: 250.6rps, 5s_failed: 0.0rps
[45.0s] succeeded: 10081, failed: 0, 5s: 248.2rps, 5s_failed: 0.0rps
[50.0s] succeeded: 11302, failed: 0, 5s: 244.2rps, 5s_failed: 0.0rps
[55.0s] succeeded: 12505, failed: 0, 5s: 240.6rps, 5s_failed: 0.0rps
[60.0s] succeeded: 13761, failed: 0, 5s: 251.2rps, 5s_failed: 0.0rps

Anubis “mild suspicion” (4, saturated Anubis Go runtime):

> target/release/pow-buster live --api-type anubis --host http://localhost:8923/ \
                                                    --n-workers 64

You are hitting host http://localhost:8923/, n_workers: 64
[0.0s] proofs accepted: 0, failed: 0, 5s: 0.0pps, 5s_failed: 0.0rps, 0.00% iowait
[5.0s] proofs accepted: 53805, failed: 0, 5s: 10761.0pps, 5s_failed: 0.0rps, 74.91% iowait
[10.0s] proofs accepted: 108805, failed: 0, 5s: 11000.0pps, 5s_failed: 0.0rps, 74.34% iowait
[15.0s] proofs accepted: 164656, failed: 0, 5s: 11170.2pps, 5s_failed: 0.0rps, 73.92% iowait
[20.0s] proofs accepted: 220786, failed: 0, 5s: 11226.0pps, 5s_failed: 0.0rps, 73.65% iowait
[25.0s] proofs accepted: 277543, failed: 0, 5s: 11351.4pps, 5s_failed: 0.0rps, 73.43% iowait
[30.0s] proofs accepted: 335189, failed: 0, 5s: 11529.2pps, 5s_failed: 0.0rps, 73.10% iowait
[35.0s] proofs accepted: 392865, failed: 0, 5s: 11535.2pps, 5s_failed: 0.0rps, 72.80% iowait
[40.0s] proofs accepted: 450552, failed: 0, 5s: 11537.4pps, 5s_failed: 0.0rps, 72.56% iowait
[45.0s] proofs accepted: 508698, failed: 0, 5s: 11629.2pps, 5s_failed: 0.0rps, 72.35% iowait
[50.0s] proofs accepted: 566663, failed: 0, 5s: 11593.0pps, 5s_failed: 0.0rps, 72.20% iowait
[55.0s] proofs accepted: 624373, failed: 0, 5s: 11542.0pps, 5s_failed: 0.0rps, 72.08% iowait
[60.0s] proofs accepted: 681909, failed: 0, 5s: 11507.2pps, 5s_failed: 0.0rps, 71.99% iowait

Anubis “extreme suspiction” (6):

> target/release/pow-buster live --api-type anubis --host http://localhost:8923/ \
                                                    --n-workers 32

You are hitting host http://localhost:8923/, n_workers: 32
[0.0s] proofs accepted: 0, failed: 0, 5s: 0.0pps, 5s_failed: 0.0rps, 0.00% iowait
[5.0s] proofs accepted: 426, failed: 0, 5s: 85.2pps, 5s_failed: 0.0rps, 0.53% iowait
[10.0s] proofs accepted: 843, failed: 0, 5s: 83.4pps, 5s_failed: 0.0rps, 0.43% iowait
[15.1s] proofs accepted: 1291, failed: 0, 5s: 89.6pps, 5s_failed: 0.0rps, 0.41% iowait
[20.0s] proofs accepted: 1727, failed: 0, 5s: 87.2pps, 5s_failed: 0.0rps, 0.39% iowait
[25.0s] proofs accepted: 2179, failed: 0, 5s: 90.4pps, 5s_failed: 0.0rps, 0.38% iowait
[30.0s] proofs accepted: 2625, failed: 0, 5s: 89.2pps, 5s_failed: 0.0rps, 0.37% iowait
[35.0s] proofs accepted: 3069, failed: 0, 5s: 88.8pps, 5s_failed: 0.0rps, 0.37% iowait
[40.0s] proofs accepted: 3477, failed: 0, 5s: 81.6pps, 5s_failed: 0.0rps, 0.36% iowait
[45.0s] proofs accepted: 3880, failed: 0, 5s: 80.6pps, 5s_failed: 0.0rps, 0.35% iowait
[50.0s] proofs accepted: 4289, failed: 0, 5s: 81.8pps, 5s_failed: 0.0rps, 0.34% iowait
[55.0s] proofs accepted: 4734, failed: 0, 5s: 89.0pps, 5s_failed: 0.0rps, 0.34% iowait
[60.0s] proofs accepted: 5180, failed: 0, 5s: 89.2pps, 5s_failed: 0.0rps, 0.34% iowait

All 32 hyperthreads of a AMD Ryzen 9 7950X are used for the end-to-end benchmark. It seems we are at the bottleneck of the server being able to record successful attempts, as further performance tuning only show improvement in offline benchmarks.

§Cap.js Browser Comparison

Cap.js is a good end-to-end comparison target since it:

  • Uses multiple sub-goals instead of one big goal, results in a normal instead of geometric distribution of solution times
  • Has an official browser benchmark performed by BrowserStack
  • Has a WASM solver written in Rust

Cap.js got the following benchmark as of 09/12/2025:

TierDeviceChromeSafari
Low-endSamsung Galaxy A114.583s-
Low-endiPhone SE (2020)-1.282s
Mid-rangeGoogle Pixel 71.027s-
Mid-rangeiPad (9th gen)1.401s
High-endGoogle Pixel 90.894s
High-endMacBook Air M30.312s0.423s

Tested with BrowserStack using the following configuration:

  • Challenge difficulty: 4
  • Number of challenges: 50
  • Salt/challenge size: 32
  • Number of benchmarks: 50

We set up a local Cap.js server, set it to the same difficulty but 5000 subgoals instead of 50.

> target/release/pow-buster cap-js --site-key 8b4574013b --url http://localhost:3000/

challenge: CapJsChallengeDescriptor { rules: CapJsChallengeRules { count: 5000, salt_length: 32, difficulty: 4 }, token: "58c59bcc0395e2ee385ed2306581d2d5720079370967838c6b" }
{
  "token": "04d15ccd0a853a79:1fa4246e098cbcf7e9d0b946a44f42",
  "expires": 1757723993381,
  "_meta": {
    "elapsed_us": 199841,
    "attempted_nonces": 326359936,
    "hashrate": 1633097992
  }
}

We solved it in ~200ms using 32-threads on a 7950X at 1.633 GH/s (faster because of hotstarting), and about 150x faster than MacBook Air M3. Taking out the thread count lead (32 threads on 7950X, 8 threads on MacBook Air M3), we are at about 40x “net” speedup per thread.

§Throughput Sanity Check

Just as a sanity check to make sure we are actually performing checks with effective data parallelism and the difference is not just because implementation overhead, here are the numbers from OpenSSL with SHA-NI support:

The program were built with -Ctarget-feature=+avx512f and -Ctarget-feature=+sha,+avx respectively and ran on 7950X with mitigations enabled.

§Single Threaded
> openssl speed sha256
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
sha256          207107.04k   645724.06k  1507281.95k  2220402.22k  2655970.10k  2687872.17k

The single-threaded throughput for OpenSSL with SHA-NI support is about 12.94 MH/s (828.2MB/s) single block, 42.00 MH/s (2.86 GB/s) continuous.

For us we have single thread:

WorkloadAVX-512 logSHA-NI logChromium SIMD128 log
SingleBlock/Anubis89.16 MH/s62.19 MH/s14.74 MH/s
DoubleBlock (mCaptcha edge case)53.28 MH/s42.55 MH/sNot Tested
go-away (32 bytes)98.42 MH/s78.10 MH/sNot Tested
Cerberus (BLAKE3)205.98 MH/sN/A49.86 MH/s

On a mobile CPU (i7-11370H), similar performance can be achieved on AVX-512 (at a higher IPC due to Intel having faster register rotations):

WorkloadAVX-512SHA-NI
SingleBlock/Anubis72.30 MH/s21.87 MH/s
DoubleBlock (mCaptcha edge case)44.84 MH/s14.46 MH/s
go-away (32 bytes)80.53 MH/s20.42 MH/s
Cerberus (BLAKE3)179.07 MH/sN/A

The throughput on 7950X for Anubis and go-away is about 100kH/s on Chromium and about 20% of that on Firefox, this is corroborated by Anubis’s own accounts in their code comments using 7950X3D empirical testing. Empirical throughput of WASM-based mCaptcha is unreliable due to lack of official benchmark tools, but should be around 2-4 MH/s, corroborated with the author’s CACM paper.

§Multi Threaded

The peak throughput on 7950X reported by openssl speed -multi 32 sha256 is 239.76 MH/s (15.34 GB/s) single block, 1.14 GH/s (73.24 GB/s) continuous.

WorkloadAVX-512 logSHA-NIVendor Official on Chromium 4
SingleBlock/Anubis1.465 GH/s1.143 GH/s~650kH/s
DoubleBlock (mCaptcha edge case)850.97 MH/s827.74 MH/sN/A
go-away (32 bytes)1.564 GH/s1.291 GH/sN/A
Cerberus (BLAKE3)3.426 GH/sN/A~465MH/s (Cherry picked from this repo)

On EPYC 9634 with better thermals, OpenSSL has 598.28 MH/s (38.29 GB/s) single block, 1.91 GH/s (122.54 GB/s) continuous.

WorkloadAVX-512SHA-NI
SingleBlock/Anubis3.387 GH/s2.09 GH/s
DoubleBlock (mCaptcha edge case)1.861 GH/s1.64 GH/s
go-away (32 bytes)3.826 GH/s3.15 GH/s
Cerberus (BLAKE3)8.874 GH/sN/A

§Security Implications and Responsible Reporting

The performance gap between optimized native code and browser JavaScript (>100x) makes it impractical to set difficulty levels that are both:

  • High enough to prevent automated solving on native hardware
  • Low enough to be solvable in browsers within reasonable timeouts

These findings suggest that both designing and adopting a PoW-based CAPTCHA systems may need additional verification mechanisms beyond empirical testing.

A good effort outreach was made to Anubis for comments on similar concerns of lacking efficacy/transparency dated 9/19/2025, but no reply was received as of 11/04/2025. email

Additionally, we had opened some issues to upstream when there are clear performance regressions (i.e. not just optimization by a factor but non-linear server-side performance degradation). Here are the current statuses:

ProjectIssue / PRReported IssueUpstream response
mCaptcha#186Difficulty inversion; Spin loop, stalls at ~200 rpsPending Since 06/05/2025
Anubis#1103Lock-convoy on certain backend caps at 5-6 k rpsFixed only for in-memory DB (pending algo tweak)
go-awaynot evaluated
Cap.js#97Difficulty inversion; Event-loop starvation, drops from 400 → 50 rpsDeclined (“out-of-scope”/suggested IP RL)
GoToSocialPR 4433Structural biasFeature removed

All load tests were performed using the live command with the following methodology:

  • For projects with multiple difficulty presets, the highest difficulty preset was used
  • All requests are strictly proof of work round-trips and contain valid proof of work. No backend service were hooked up.
  • Supplementary features that are irrelevant to this study such as traditional IP rate-limiting were disabled.
  • These tests were performed on a 32-core AMD Ryzen 9 7950X, actual ratio/capacity may vary depending on server capacity and topology.
  • “difficulty inversion” was defined as a the server not being able to fully load all 32-cores at at least 1:1 latency (as reported by http_wait metric at cutoff 50%) or 1:1 CPU usage to pow-buster’s throughput.

§Future Work (i.e. Okay, so what would be a good PoW then?)

See FUTURE.md

§Conflict of Interest Disclosure

This work is not funded or sponsored by any external entity and entirely my own research on my own time. While I personally hold negative ethical and technical position against using Proof of Work for the open-web in general, no vendor, competitor, professional affiliation or bounty program otherwise influenced its content.

For benchmarks conducted against vendor code, I am happy to rerun and/or clarify any part of the analysis by request if any vendor believes particular performance characteristics demonstrated here no longer apply or requires further clarification. Create an issue with:

  • An official release or beta-release tag that you want to be benchmarked.
  • Proposed methodology (commands to build your project, environment setup, etc).

I will rerun the benchmarks and update relavant sections and keep all communications on record.

§Contributing / Wishlist

Contributions are welcome, roughly in priority order we want:

  1. General profiling and further optimization.
  2. Would be nice to have a WebGPU solution that can be used in a UserScript.
  3. An AVX-2 solution and corresponding benchmark. (low priority as this isn’t really a “product”)

§License and Acknowledgments

This project is licensed under the Apache License 2.0. See the LICENSE file for details.

This project contains some copy pasted or minimally modified/transpiled code from:


  1. Adversarial refers to challenges are solved using the path-of-least-resistance, sometimes involving massaging nonce space into favorable conditions or partially inverting hash images into lower-latency internal states. Most schemes supported do not have explicit specifications and depend on the cryptographic guarantees of the hash function, which I did not break (at least not in a previously unknown way). This code follows the original code to the letter of the law and sometimes emit awkward but computationally or statistically favorable solutions (such as 10000000073377131, -10.00000141128212, etc.) 

  2. Represents a custom implementation using safe, externally-validated cryptographic abstractions only and no platform-specific optimizations. 

  3. Manivannan, A.; Sethuraman, S. C.; Vimala Sudhakaran, D. P. MCaptcha: Replacing Captchas with Rate Limiters to Improve Security and Accessibility. Communications of the ACM 2024, 67 (10), 70–80. https://doi.org/10.1145/3660628

  4. Due to instablity of WASM optimization and runtime throttling behavior and lack of vendor provided benchmark harness, only approximate numbers can be provided. 

Modules§

message
Message builders
solver
Solvers

Structs§

Align16
Align to 16 bytes
Align64
Align to 64 bytes

Constants§

BLAKE3_SOLVER_NAME
Blake3 solver name
SOLVER_NAME
Solver name

Traits§

AlignerTo
A trait for a trivial aligner that has no function except setting the alignment and transparently holding a value of type T.

Functions§

build_mcaptcha_prefix
Build a prefix for mCaptcha PoW
compute_mask_anubis
Compute the mask for an Anubis PoW (mask & (V[0] << 32 | V[1]) == 0)
compute_mask_cerberus
Compute a mask for a Cerberus PoW (mask & (V[0] << 32) == 0)
compute_mask_goaway
Compute the mask for a GoAway PoW (mask & (V[0] << 32) == 0)
compute_target_mcaptcha
Compute the target for an mCaptcha PoW
encode_hex
Encode a sha-256 hash into hex
encode_hex_le
Encode a blake3 hash into hex
extract128_be
Extract top 128 bits from a 64-bit word array

Type Aliases§

BinarySolver
Binary solver
CerberusSolver
Cerberus solver
DecimalSolver
Dynamic dispatching Decimal solver
DoubleBlockSolver
Double block solver
GoAwaySolver
Go away solver
SingleBlockSolver
Single block solver