cd /news/artificial-intelligence/vibe-slopped-cryptography · home › topics › artificial-intelligence › article
[ARTICLE · art-166533] src=moq.dev ↗ pub= topic=artificial-intelligence verified=true sentiment=↑ positive

Vibe Slopped Cryptography

A developer known as kixelated released rind, a Rust AES-128-GCM cryptography library written largely by Anthropic's Claude (Opus), which benchmarks faster than aws-lc-rs and ring at both build and runtime. In rind's benchmark report at commit ccdda859 run 2026-11-09, rind sealed 32-byte packets in 19.3 ns on Arrow Lake versus 37.2 ns for aws-lc-rs and 40.3 ns for ring, and built in 3.4 s versus 11.8 s for aws-lc-rs and 5.0 s for ring, a 12× build speedup and 1.63× (Arrow Lake) to 1.72× (Zen 3) geometric-mean runtime gain over aws-lc-rs. The author said the result matters because AES-128-GCM is the most widely used TLS cipher suite, so small per-request CPU savings compound across HTTPS traffic; rind began as a fork of Graviola and combines code from ring, aws-lc-rs and libcrux.

read59 min views2 publishedNov 9, 2026
Vibe Slopped Cryptography
Image: source

November 8, 2026 · kixelated

I’m one of the OG “rewrite it in Rust” guys. I love Rust.

Unfortunately, I wrote my last line of Rust 6 months ago. I still want Claude to write everything in Rust, but it’s difficult when rustc turns my desktop into lava.

I spent some tokens investigating on how to speed up builds for MoQ. One finding was that aws-lc-rs takes 60s+ to build. wtf why does a single crate take a full minute to build?

Despite the suffix, aws-lc-rs is actually a C library in disguise. Same with the next best crypto library: ring. wtf is C doing in my Rust library.

I did what any sane software engineer does in current_year, I pulled a 9-year old gaming PC out of the closet, installed Claude, and ran /goal rewrite it in rust *.

  • and a lot of assembly

WOW FAST #

rind is vibe slopped crypto. This statement alone should fill me with mortal dread, but AI is advancing so quickly that it’s no longer absurd.

Not only was Opus able to make builds faster, it made the runtime faster too.

aws-lc-rs's

packets per core

AES-128-GCM, the geometric mean over CPUs. Arrow Lake: 1.63×, Zen 3: 1.72×, Coffee Lake: 1.12×, Apple M4: 1.11×. aws-lc is Amazon's BoringSSL fork. On Mac, rind holds DIT (constant-time mode) across each batch.

Data #

Library Arrow Lake, 32 B Arrow Lake, 1350 B Zen 3, 32 B Zen 3, 1350 B Coffee Lake, 32 B Coffee Lake, 1350 B Apple M4, 32 B Apple M4, 1350 B
rind 19.3 ns 91.0 ns 41.2 ns 164 ns 44.1 ns 253 ns 9.30 ns 162 ns
aws-lc-rs 37.2 ns 149 ns 72.7 ns 282 ns 88.1 ns 283 ns 48.6 ns 179 ns
ring 40.3 ns 120 ns 54.3 ns 185 ns 69.7 ns 280 ns 42.1 ns 212 ns
RustCrypto 73.1 ns 273 ns 94.7 ns 433 ns 99.7 ns 545 ns 23.7 ns 213 ns
graviola 41.3 ns 221 ns 67.5 ns 294 ns 70.4 ns 392 ns 78.4 ns 214 ns
libcrux 167 ns 1.94 µs 310 ns 3.90 µs 281 ns 3.51 µs 52.4 ns 597 ns
OpenSSL 55.5 ns 159 ns 115 ns 317 ns 150 ns 348 ns 65.2 ns 198 ns

AES-128-GCM seal, criterion's estimate from rind's benchmark report at ccdda859, run 2026-11-09: Arrow Lake is Intel(R) Core(TM) Ultra 7 270K Plus, Zen 3 is AMD Ryzen 9 5900XT 16-Core Processor, Coffee Lake is Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz, Apple M4 is Apple M4. On Mac, rind holds DIT across the timed loop, as a caller batching packets does.

^ This is a big deal because AES-128-GCM is the most popular TLS cipher suite by far. Even this relatively tiny reduction in CPU usage has huge impact when multiplied across every HTTPS request in the world*.

Rind started as fork of Graviola and quickly morphed into a monsterish combination of ring and aws-lc-rs (both fork BoringSSL, a fork of OpenSSL). Bits of libcrux were throw in there for good measure.

The engineers who developed these libraries are smarter than me. But I have a credit card in current_year and don’t need to be smart any more.

  • this benchmark is HTTP/3 specific. HTTP/1 and HTTP/2 use different payload sizes.

WOW FAST #

Rust gets dunked on for compile speeds but nerds forget that C/C++ can also be terrible.

faster to

build

24.2 s race clock, 12× speed

The geometric mean over CPUs. Arrow Lake: 3.7×, Zen 3: 3.9×, Coffee Lake: 2.9×, Apple M4: 5.1×.

Data #

CPU Build Time CPU time Binary Tools
Arrow Lake rind 3.4 s 8.0 s 0.84 MiB rustc only
Arrow Lake aws-lc-rs 11.8 s 36.9 s 2.85 MiB needs C compiler
Arrow Lake ring 5.0 s 7.3 s 0.71 MiB needs C compiler
Arrow Lake RustCrypto 2.8 s 15.8 s 0.52 MiB rustc only
Arrow Lake graviola 1.9 s 4.2 s 0.87 MiB rustc only
Arrow Lake libcrux 4.8 s 11.6 s 0.71 MiB rustc only
Arrow Lake OpenSSL 2.8 s 7.4 s 0.36 MiB needs C compiler, pkg-config
Arrow Lake openssl-vendored 17.9 s 136.7 s 4.90 MiB needs C compiler, make, perl
Arrow Lake rustls + rind 3.9 s 20.2 s 2.85 MiB rustc only
Arrow Lake rustls + rind-lean 3.8 s 20.2 s 1.73 MiB rustc only
Arrow Lake rustls + aws-lc-rs 14.4 s 49.2 s 3.92 MiB needs C compiler
Arrow Lake rustls + ring 7.5 s 19.1 s 1.85 MiB needs C compiler
Zen 3 rind 4.5 s 10.6 s 0.84 MiB rustc only
Zen 3 aws-lc-rs 16.3 s 54.6 s 2.85 MiB needs C compiler
Zen 3 ring 6.7 s 9.5 s 0.71 MiB needs C compiler
Zen 3 RustCrypto 4.0 s 20.7 s 0.52 MiB rustc only
Zen 3 graviola 2.6 s 5.3 s 0.87 MiB rustc only
Zen 3 libcrux 6.8 s 15.8 s 0.71 MiB rustc only
Zen 3 OpenSSL 3.9 s 9.6 s 0.36 MiB needs C compiler, pkg-config
Zen 3 openssl-vendored 22.8 s 201.7 s 4.90 MiB needs C compiler, make, perl
Zen 3 rustls + rind 5.2 s 26.2 s 2.85 MiB rustc only
Zen 3 rustls + rind-lean 5.2 s 26.1 s 1.73 MiB rustc only
Zen 3 rustls + aws-lc-rs 20.6 s 70.0 s 3.92 MiB needs C compiler
Zen 3 rustls + ring 10.1 s 24.0 s 1.85 MiB needs C compiler
Coffee Lake rind 7.3 s 13.0 s 0.84 MiB rustc only
Coffee Lake aws-lc-rs 26.0 s 62.7 s 2.85 MiB needs C compiler
Coffee Lake ring 9.3 s 12.1 s 0.71 MiB needs C compiler
Coffee Lake RustCrypto 8.8 s 25.6 s 0.52 MiB rustc only
Coffee Lake graviola 4.2 s 7.1 s 0.87 MiB rustc only
Coffee Lake libcrux 10.2 s 21.7 s 0.71 MiB rustc only
Coffee Lake OpenSSL 6.2 s 12.5 s 0.36 MiB needs C compiler, pkg-config
Coffee Lake openssl-vendored 83.3 s 221.9 s 4.90 MiB needs C compiler, make, perl
Coffee Lake rustls + rind 11.4 s 32.1 s 2.85 MiB rustc only
Coffee Lake rustls + rind-lean 11.3 s 32.1 s 1.73 MiB rustc only
Coffee Lake rustls + aws-lc-rs 33.6 s 82.0 s 3.92 MiB needs C compiler
Coffee Lake rustls + ring 16.2 s 30.4 s 1.85 MiB needs C compiler
Apple M4 rind 4.1 s 7.9 s 0.66 MiB rustc only
Apple M4 aws-lc-rs 29.3 s 93.2 s 2.04 MiB needs C compiler
Apple M4 ring 8.2 s 10.2 s 0.61 MiB needs C compiler
Apple M4 RustCrypto 5.2 s 16.3 s 0.44 MiB rustc only
Apple M4 graviola 3.1 s 5.5 s 0.78 MiB rustc only
Apple M4 libcrux 8.1 s 18.0 s 0.56 MiB rustc only
Apple M4 OpenSSL 4.6 s 10.2 s 0.34 MiB needs C compiler
Apple M4 openssl-vendored 132.5 s 425.8 s 3.58 MiB needs C compiler, make, perl
Apple M4 rustls + rind 6.7 s 22.4 s 2.07 MiB rustc only
Apple M4 rustls + rind-lean 6.9 s 22.8 s 1.47 MiB rustc only
Apple M4 rustls + aws-lc-rs 34.5 s 111.0 s 2.93 MiB needs C compiler
Apple M4 rustls + ring 12.3 s 23.0 s 1.53 MiB needs C compiler

rind's admin/build-cost: the median of cold builds with an empty target directory and a warm download cache. Arrow Lake: Core Ultra 7 270K Plus, 12 jobs, 3 runs, 2026-11-09, at ccdda859; Zen 3: Ryzen 9 5900XT, 16 jobs, 3 runs, 2026-11-09, at ccdda859; Coffee Lake: Core i7-8700, 3 jobs, 3 runs, 2026-11-09, at ccdda859; Apple M4: Apple M4, 4 jobs, 3 runs, 2026-11-09, at ccdda859. A tool counts when the build fails without it.

Most of the time these builds are cached anyway but IDK it’s still nice to see smaller number. PSA You should be using mbx for Rust instead of complaining on Twitter about cargo target sizee and build times.

Also it’s nice from a maintainer point of view because aws-lc-rs does not compile on a lot of machines. rind doesn’t support every architecture yet either only because I don’t have test hardware.

Wow fast #

Having accomplished my goal of making MoQ faster, I let my 9-year-old gaming PC take a vacation. This poor machine was awoken from retirement and forced to run crypto benchmarks.

lul jk I ran: /goal: Support every algorithm, and make it the fastest.

timings where rind is fastest,

or within 10%

Squares: Arrow Lake, Zen 3, Coffee Lake, Apple M4. Blank: not offered. On Mac, rind holds DIT (constant-time mode) across each batch.

Data #

Operation rind aws-lc-rs ring graviola OpenSSL RustCrypto libcrux
full handshake, X25519MLKEM768 175 µs / 233 µs / 299 µs / 172 µs 237 µs / 304 µs / 438 µs / 212 µs - / - / - / - 188 µs / 248 µs / 374 µs / 179 µs 433 µs / 638 µs / 824 µs / 457 µs - / - / - / - - / - / - / -
full handshake, X25519 151 µs / 202 µs / 255 µs / 151 µs 201 µs / 259 µs / 365 µs / 185 µs 221 µs / 284 µs / 334 µs / 185 µs 161 µs / 212 µs / 314 µs / 159 µs 371 µs / 545 µs / 679 µs / 374 µs - / - / - / - - / - / - / -
full handshake, P-256 174 µs / 234 µs / 291 µs / 171 µs 231 µs / 297 µs / 416 µs / 206 µs 219 µs / 282 µs / 325 µs / 200 µs 192 µs / 252 µs / 360 µs / 190 µs 400 µs / 602 µs / 750 µs / 399 µs - / - / - / - - / - / - / -
full handshake, Ed25519 certificate 121 µs / 164 µs / 210 µs / 126 µs 167 µs / 216 µs / 304 µs / 151 µs 202 µs / 276 µs / 322 µs / 154 µs 123 µs / 165 µs / 246 µs / 125 µs 368 µs / 617 µs / 741 µs / 382 µs - / - / - / - - / - / - / -
full handshake, RSA-2048 certificate 423 µs / 510 µs / 613 µs / 371 µs 479 µs / 619 µs / 721 µs / 407 µs 496 µs / 634 µs / 672 µs / 447 µs 443 µs / 549 µs / 679 µs / 674 µs 675 µs / 885 µs / 1.00 ms / 642 µs - / - / - / - - / - / - / -
resumed handshake, X25519 52.5 µs / 74.9 µs / 113 µs / 65.1 µs 101 µs / 130 µs / 213 µs / 90.3 µs 111 µs / 154 µs / 183 µs / 87.0 µs 54.1 µs / 75.5 µs / 149 µs / 62.1 µs 230 µs / 362 µs / 458 µs / 252 µs - / - / - / - - / - / - / -
1 MB transfer, AES-128-GCM 170 µs / 271 µs / 436 µs / 298 µs 237 µs / 428 µs / 440 µs / 295 µs 170 µs / 271 µs / 443 µs / 360 µs 285 µs / 421 µs / 577 µs / 315 µs 253 µs / 461 µs / 489 µs / 324 µs - / - / - / - - / - / - / -
1 MB transfer, AES-256-GCM 183 µs / 284 µs / 547 µs / 334 µs 267 µs / 453 µs / 551 µs / 327 µs 185 µs / 287 µs / 545 µs / 370 µs 334 µs / 479 µs / 687 µs / 387 µs 285 µs / 492 µs / 599 µs / 360 µs - / - / - / - - / - / - / -
1 MB transfer, ChaCha20-Poly1305 587 µs / 682 µs / 919 µs / 1.11 ms 585 µs / 684 µs / 922 µs / 1.10 ms 582 µs / 683 µs / 924 µs / 1.10 ms 1.15 ms / 1.37 ms / 1.94 ms / 1.75 ms 650 µs / 783 µs / 990 µs / 1.10 ms - / - / - / - - / - / - / -
AES-128-GCM seal, 32 B 19.3 ns / 41.2 ns / 44.1 ns / 9.30 ns 37.2 ns / 72.7 ns / 88.1 ns / 48.6 ns 40.3 ns / 54.3 ns / 69.7 ns / 42.1 ns 41.3 ns / 67.5 ns / 70.4 ns / 78.4 ns 55.5 ns / 115 ns / 150 ns / 65.2 ns 73.1 ns / 94.7 ns / 99.7 ns / 23.7 ns 167 ns / 310 ns / 281 ns / 52.4 ns
AES-128-GCM seal, 1350 B 91.0 ns / 164 ns / 253 ns / 162 ns 149 ns / 282 ns / 283 ns / 179 ns 120 ns / 185 ns / 280 ns / 212 ns 221 ns / 294 ns / 392 ns / 214 ns 159 ns / 317 ns / 348 ns / 198 ns 273 ns / 433 ns / 545 ns / 213 ns 1.94 µs / 3.90 µs / 3.51 µs / 597 ns
AES-128-GCM seal, 16 KB 810 ns / 1.52 µs / 2.33 µs / 1.42 µs 1.31 µs / 2.58 µs / 2.41 µs / 1.45 µs 814 ns / 1.41 µs / 2.38 µs / 1.94 µs 2.03 µs / 2.56 µs / 3.73 µs / 1.59 µs 1.33 µs / 2.63 µs / 2.46 µs / 1.51 µs 2.46 µs / 4.18 µs / 5.54 µs / 2.28 µs 21.9 µs / 44.4 µs / 39.4 µs / 6.76 µs
AES-128-GCM open, 32 B 14.9 ns / 32.9 ns / 39.5 ns / 11.3 ns 37.4 ns / 72.2 ns / 88.1 ns / 46.5 ns 40.4 ns / 58.4 ns / 77.2 ns / 39.2 ns 36.3 ns / 64.5 ns / 67.9 ns / 84.4 ns 59.9 ns / 123 ns / 156 ns / 65.7 ns 78.1 ns / 102 ns / 105 ns / 27.4 ns 158 ns / 321 ns / 300 ns / 61.3 ns
AES-128-GCM open, 1350 B 87.9 ns / 160 ns / 238 ns / 175 ns 147 ns / 295 ns / 282 ns / 190 ns 112 ns / 186 ns / 274 ns / 242 ns 174 ns / 306 ns / 356 ns / 225 ns 158 ns / 336 ns / 354 ns / 197 ns 282 ns / 451 ns / 561 ns / 233 ns 1.95 µs / 3.92 µs / 3.46 µs / 625 ns
AES-128-GCM open, 16 KB 798 ns / 1.45 µs / 2.51 µs / 1.55 µs 1.26 µs / 2.72 µs / 2.57 µs / 1.57 µs 811 ns / 1.49 µs / 2.56 µs / 2.15 µs 1.40 µs / 2.67 µs / 3.35 µs / 1.70 µs 1.29 µs / 2.78 µs / 2.66 µs / 1.66 µs 2.51 µs / 4.33 µs / 5.71 µs / 2.43 µs 21.8 µs / 44.3 µs / 38.7 µs / 6.76 µs
AES-256-GCM seal, 32 B 21.1 ns / 44.9 ns / 48.0 ns / 10.1 ns 39.5 ns / 80.0 ns / 93.2 ns / 51.9 ns 43.4 ns / 57.4 ns / 73.8 ns / 44.7 ns 44.8 ns / 74.7 ns / 77.4 ns / 78.3 ns 59.6 ns / 121 ns / 157 ns / 66.0 ns 77.3 ns / 101 ns / 108 ns / 24.7 ns 217 ns / 426 ns / 340 ns / 51.9 ns
AES-256-GCM seal, 1350 B 107 ns / 188 ns / 327 ns / 188 ns 175 ns / 310 ns / 360 ns / 200 ns 134 ns / 205 ns / 354 ns / 216 ns 257 ns / 337 ns / 476 ns / 258 ns 182 ns / 342 ns / 421 ns / 220 ns 313 ns / 490 ns / 622 ns / 246 ns 2.82 µs / 6.59 µs / 4.42 µs / 624 ns
AES-256-GCM seal, 16 KB 923 ns / 1.54 µs / 3.20 µs / 1.70 µs 1.58 µs / 2.77 µs / 3.30 µs / 1.70 µs 941 ns / 1.55 µs / 3.22 µs / 2.04 µs 2.42 µs / 2.98 µs / 4.63 µs / 2.14 µs 1.58 µs / 2.81 µs / 3.38 µs / 1.77 µs 2.87 µs / 4.78 µs / 6.42 µs / 2.68 µs 32.2 µs / 76.1 µs / 50.4 µs / 6.94 µs
AES-256-GCM open, 32 B 16.9 ns / 37.7 ns / 43.3 ns / 12.2 ns 37.0 ns / 81.9 ns / 92.0 ns / 48.7 ns 41.3 ns / 62.9 ns / 80.6 ns / 39.6 ns 37.4 ns / 67.9 ns / 72.9 ns / 83.4 ns 62.0 ns / 127 ns / 162 ns / 68.0 ns 82.0 ns / 109 ns / 111 ns / 40.8 ns 216 ns / 438 ns / 362 ns / 65.8 ns
AES-256-GCM open, 1350 B 96.9 ns / 176 ns / 310 ns / 195 ns 169 ns / 319 ns / 360 ns / 215 ns 121 ns / 202 ns / 346 ns / 246 ns 204 ns / 341 ns / 436 ns / 263 ns 186 ns / 360 ns / 424 ns / 224 ns 318 ns / 505 ns / 641 ns / 264 ns 2.82 µs / 6.62 µs / 4.42 µs / 655 ns
AES-256-GCM open, 16 KB 904 ns / 1.62 µs / 3.40 µs / 1.80 µs 1.56 µs / 2.92 µs / 3.46 µs / 1.82 µs 923 ns / 1.65 µs / 3.45 µs / 2.23 µs 1.72 µs / 3.04 µs / 4.26 µs / 2.16 µs 1.60 µs / 2.98 µs / 3.53 µs / 1.92 µs 2.92 µs / 4.93 µs / 6.61 µs / 2.82 µs 32.2 µs / 77.9 µs / 49.8 µs / 7.15 µs
ChaCha20-Poly1305 seal, 32 B 98.5 ns / 114 ns / 122 ns / 145 ns 103 ns / 120 ns / 135 ns / 157 ns 99.1 ns / 116 ns / 122 ns / 145 ns 180 ns / 215 ns / 218 ns / 195 ns 175 ns / 256 ns / 316 ns / 216 ns 1.05 µs / 1.18 µs / 1.13 µs / 342 ns 156 ns / 218 ns / 271 ns / 170 ns
ChaCha20-Poly1305 seal, 1350 B 438 ns / 530 ns / 670 ns / 744 ns 446 ns / 532 ns / 684 ns / 759 ns 440 ns / 531 ns / 672 ns / 738 ns 892 ns / 1.08 µs / 1.20 µs / 1.22 µs 580 ns / 736 ns / 910 ns / 823 ns 1.68 µs / 1.93 µs / 2.04 µs / 1.74 µs 1.75 µs / 2.32 µs / 2.97 µs / 1.93 µs
ChaCha20-Poly1305 seal, 16 KB 4.12 µs / 4.58 µs / 6.24 µs / 7.48 µs 4.13 µs / 4.54 µs / 6.29 µs / 7.47 µs 4.18 µs / 4.52 µs / 6.30 µs / 7.49 µs 8.21 µs / 9.83 µs / 11.7 µs / 12.4 µs 4.41 µs / 5.07 µs / 6.25 µs / 7.34 µs 8.01 µs / 9.78 µs / 11.8 µs / 14.9 µs 19.4 µs / 25.9 µs / 33.4 µs / 21.7 µs
XChaCha20-Poly1305 seal, 32 B 186 ns / 227 ns / 259 ns / 875 ns 199 ns / 251 ns / 275 ns / 861 ns - / - / - / - 254 ns / 337 ns / 333 ns / 908 ns - / - / - / - 1.14 µs / 1.30 µs / 1.27 µs / 1.05 µs 241 ns / 328 ns / 396 ns / 895 ns
XChaCha20-Poly1305 seal, 1350 B 529 ns / 644 ns / 805 ns / 1.48 µs 541 ns / 665 ns / 829 ns / 1.46 µs - / - / - / - 971 ns / 1.20 µs / 1.32 µs / 1.93 µs - / - / - / - 1.76 µs / 2.05 µs / 2.18 µs / 2.44 µs 1.84 µs / 2.44 µs / 3.10 µs / 2.71 µs
XChaCha20-Poly1305 seal, 16 KB 4.20 µs / 4.78 µs / 6.39 µs / 8.30 µs 4.21 µs / 4.79 µs / 6.46 µs / 8.25 µs - / - / - / - 8.29 µs / 10.0 µs / 11.7 µs / 13.2 µs - / - / - / - 8.27 µs / 9.91 µs / 12.0 µs / 15.5 µs 19.5 µs / 25.9 µs / 33.4 µs / 22.6 µs
AES-128 header protection 1.71 ns / 3.78 ns / 4.76 ns / 2.75 ns 3.58 ns / 6.00 ns / 7.65 ns / 2.83 ns 3.41 ns / 6.98 ns / 7.66 ns / 3.19 ns - / - / - / - - / - / - / - - / - / - / - - / - / - / -
AES-256 header protection 2.13 ns / 4.85 ns / 5.91 ns / 2.74 ns 3.89 ns / 8.05 ns / 9.39 ns / 2.99 ns 5.13 ns / 9.63 ns / 9.36 ns / 3.90 ns - / - / - / - - / - / - / - - / - / - / - - / - / - / -
ChaCha20 header protection 53.0 ns / 60.8 ns / 78.8 ns / 57.8 ns 68.4 ns / 81.4 ns / 97.8 ns / 72.9 ns 60.3 ns / 74.5 ns / 87.4 ns / 67.8 ns - / - / - / - - / - / - / - - / - / - / - - / - / - / -
X25519 17.9 µs / 23.6 µs / 24.7 µs / 16.5 µs 19.4 µs / 24.2 µs / 30.8 µs / 17.7 µs 34.9 µs / 45.3 µs / 53.8 µs / 24.5 µs 18.5 µs / 23.6 µs / 25.0 µs / 16.6 µs 33.3 µs / 48.0 µs / 54.5 µs / 35.8 µs 36.2 µs / 51.9 µs / 56.1 µs / 29.6 µs 42.2 µs / 62.4 µs / 72.2 µs / 37.3 µs
P-256 ECDH 29.4 µs / 38.7 µs / 42.4 µs / 26.3 µs 31.8 µs / 40.8 µs / 50.9 µs / 28.7 µs 33.6 µs / 41.8 µs / 46.9 µs / 32.5 µs 33.2 µs / 41.8 µs / 45.9 µs / 31.0 µs 52.2 µs / 68.6 µs / 80.1 µs / 50.1 µs 123 µs / 254 µs / 232 µs / 180 µs 168 µs / 247 µs / 275 µs / 182 µs
Ed25519 sign 4.12 µs / 5.74 µs / 6.62 µs / 3.93 µs 4.48 µs / 6.11 µs / 7.20 µs / 4.07 µs 13.1 µs / 17.1 µs / 20.8 µs / 7.05 µs 4.39 µs / 5.83 µs / 6.79 µs / 4.17 µs 13.5 µs / 23.3 µs / 26.7 µs / 16.5 µs 9.57 µs / 13.4 µs / 15.1 µs / 8.63 µs 28.5 µs / 40.7 µs / 46.9 µs / 22.1 µs
Ed25519 verify 19.1 µs / 24.9 µs / 27.3 µs / 16.6 µs 21.4 µs / 27.0 µs / 29.6 µs / 18.4 µs 25.9 µs / 34.9 µs / 38.1 µs / 20.0 µs 19.3 µs / 25.0 µs / 27.4 µs / 16.6 µs 45.1 µs / 77.6 µs / 86.5 µs / 40.6 µs 22.0 µs / 24.5 µs / 26.1 µs / 18.5 µs 42.6 µs / 53.4 µs / 60.3 µs / 29.4 µs
P-256 ECDSA sign 6.61 µs / 8.56 µs / 12.9 µs / 7.18 µs 12.2 µs / 11.9 µs / 19.5 µs / 11.2 µs 12.2 µs / 12.8 µs / 14.7 µs / 11.0 µs 8.98 µs / 10.4 µs / 20.2 µs / 8.58 µs 14.1 µs / 16.4 µs / 20.2 µs / 12.4 µs 31.1 µs / 65.2 µs / 68.1 µs / 44.4 µs 60.6 µs / 86.6 µs / 101 µs / 66.8 µs
P-256 ECDSA verify 30.6 µs / 38.3 µs / 41.3 µs / 26.0 µs 30.4 µs / 38.1 µs / 43.0 µs / 27.2 µs 33.8 µs / 39.3 µs / 43.6 µs / 29.1 µs 32.3 µs / 39.9 µs / 44.1 µs / 28.2 µs 45.6 µs / 56.4 µs / 67.7 µs / 41.7 µs 103 µs / 216 µs / 197 µs / 151 µs 145 µs / 207 µs / 234 µs / 156 µs
SHA-256, 64 B 29.9 ns / 52.7 ns / 236 ns / 37.0 ns 56.6 ns / 94.4 ns / 314 ns / 67.2 ns 57.4 ns / 77.4 ns / 273 ns / 44.3 ns 39.5 ns / 61.9 ns / 568 ns / 34.8 ns 156 ns / 231 ns / 505 ns / 159 ns 39.0 ns / 55.0 ns / 469 ns / 36.5 ns 218 ns / 334 ns / 485 ns / 226 ns
SHA-256, 1350 B 268 ns / 576 ns / 2.42 µs / 410 ns 306 ns / 619 ns / 2.78 µs / 440 ns 299 ns / 608 ns / 2.74 µs / 412 ns 292 ns / 588 ns / 6.11 µs / 474 ns 412 ns / 754 ns / 2.66 µs / 524 ns 295 ns / 589 ns / 5.00 µs / 473 ns 2.28 µs / 3.56 µs / 5.19 µs / 2.49 µs
SHA-256, 16 KB 3.24 µs / 6.74 µs / 27.7 µs / 4.96 µs 3.23 µs / 6.78 µs / 31.5 µs / 4.87 µs 3.26 µs / 6.78 µs / 31.2 µs / 4.84 µs 3.21 µs / 6.76 µs / 70.3 µs / 6.06 µs 3.33 µs / 6.92 µs / 28.0 µs / 4.99 µs 3.21 µs / 6.75 µs / 57.7 µs / 5.70 µs 27.3 µs / 41.7 µs / 60.7 µs / 29.2 µs
SHA-512, 64 B 59.8 ns / 131 ns / 194 ns / 76.1 ns 134 ns / 212 ns / 227 ns / 106 ns 140 ns / 188 ns / 202 ns / 86.6 ns 147 ns / 184 ns / 237 ns / 175 ns 228 ns / 317 ns / 430 ns / 209 ns 118 ns / 193 ns / 266 ns / 77.2 ns 166 ns / 229 ns / 286 ns / 141 ns
SHA-512, 1350 B 248 ns / 1.23 µs / 1.62 µs / 731 ns 1.24 µs / 1.78 µs / 1.95 µs / 767 ns 1.24 µs / 1.75 µs / 1.93 µs / 737 ns 1.47 µs / 1.75 µs / 2.34 µs / 1.87 µs 1.19 µs / 1.44 µs / 1.90 µs / 865 ns 1.18 µs / 1.80 µs / 2.64 µs / 716 ns 1.69 µs / 2.37 µs / 3.04 µs / 1.57 µs
SHA-512, 16 KB 2.63 µs / 14.0 µs / 18.5 µs / 8.68 µs 14.1 µs / 20.2 µs / 21.7 µs / 8.72 µs 14.3 µs / 20.3 µs / 21.6 µs / 8.70 µs 17.8 µs / 20.1 µs / 27.0 µs / 21.8 µs 12.3 µs / 14.5 µs / 19.0 µs / 8.85 µs 13.4 µs / 20.6 µs / 30.6 µs / 8.47 µs 20.1 µs / 27.3 µs / 35.0 µs / 18.3 µs
HMAC-SHA256, 64 B 72.7 ns / 130 ns / 621 ns / 99.7 ns 176 ns / 263 ns / 799 ns / 244 ns 142 ns / 215 ns / 700 ns / 135 ns 107 ns / 168 ns / 1.43 µs / 112 ns 1.55 µs / 2.52 µs / 3.70 µs / 2.05 µs 103 ns / 156 ns / 1.19 µs / 99.5 ns 530 ns / 833 ns / 1.19 µs / 563 ns
HMAC-SHA256, 1350 B 321 ns / 655 ns / 2.77 µs / 478 ns 427 ns / 794 ns / 3.27 µs / 600 ns 400 ns / 749 ns / 3.24 µs / 503 ns 356 ns / 694 ns / 7.06 µs / 558 ns 1.78 µs / 3.01 µs / 5.91 µs / 2.44 µs 353 ns / 681 ns / 5.72 µs / 541 ns 2.67 µs / 4.11 µs / 5.96 µs / 2.80 µs
HKDF-SHA256 extract and expand 148 ns / 252 ns / 1.06 µs / 205 ns 288 ns / 376 ns / 1.28 µs / 331 ns 307 ns / 399 ns / 1.18 µs / 268 ns - / - / - / - 1.72 µs / 2.71 µs / 4.37 µs / 2.18 µs 220 ns / 310 ns / 1.95 µs / 211 ns 968 ns / 1.37 µs / 2.00 µs / 926 ns
HKDF-SHA256 expand 47.4 ns / 87.8 ns / 292 ns / 70.1 ns 126 ns / 179 ns / 624 ns / 154 ns 120 ns / 142 ns / 326 ns / 93.1 ns - / - / - / - 1.26 µs / 2.00 µs / 2.93 µs / 1.58 µs 83.7 ns / 103 ns / 501 ns / 68.1 ns 450 ns / 706 ns / 1.00e+3 ns / 480 ns
RSA-2048 PKCS#1 sign 345 µs / 392 µs / 449 µs / 274 µs 344 µs / 432 µs / 445 µs / 283 µs 342 µs / 423 µs / 431 µs / 323 µs 344 µs / 407 µs / 444 µs / 553 µs 389 µs / 437 µs / 450 µs / 341 µs 580 µs / 988 µs / 1.14 ms / 587 µs - / - / - / -
RSA-2048 PKCS#1 verify 8.89 µs / 11.2 µs / 12.8 µs / 8.42 µs 10.8 µs / 13.6 µs / 15.5 µs / 9.51 µs 12.8 µs / 15.4 µs / 16.3 µs / 11.0 µs 14.0 µs / 17.5 µs / 19.5 µs / 18.5 µs 15.5 µs / 20.7 µs / 24.8 µs / 16.5 µs 29.1 µs / 50.2 µs / 57.3 µs / 30.9 µs - / - / - / -
RSA-2048 PSS sign 341 µs / 394 µs / 453 µs / 276 µs 352 µs / 434 µs / 452 µs / 286 µs 336 µs / 425 µs / 435 µs / 326 µs 338 µs / 410 µs / 444 µs / 553 µs 404 µs / 441 µs / 454 µs / 341 µs 581 µs / 991 µs / 1.12 ms / 587 µs 3.71 ms / 4.93 ms / 7.16 ms / 4.46 ms
RSA-2048 PSS verify 9.11 µs / 11.5 µs / 14.3 µs / 8.76 µs 11.1 µs / 14.1 µs / 17.0 µs / 9.83 µs 13.4 µs / 16.0 µs / 18.1 µs / 11.4 µs 14.3 µs / 17.9 µs / 22.3 µs / 18.8 µs 16.2 µs / 21.8 µs / 27.0 µs / 17.3 µs 35.3 µs / 58.9 µs / 69.3 µs / 39.1 µs 250 µs / 284 µs / 384 µs / 298 µs
ML-KEM-768 key generation 6.28 µs / 7.90 µs / 10.0 µs / 6.00 µs 8.43 µs / 9.43 µs / 18.4 µs / 7.38 µs - / - / - / - 7.36 µs / 8.53 µs / 10.0 µs / 6.11 µs 19.8 µs / 26.4 µs / 40.3 µs / 24.9 µs 39.8 µs / 57.6 µs / 59.8 µs / 26.3 µs 15.0 µs / 17.2 µs / 19.8 µs / 11.8 µs
ML-KEM-768 encapsulate 6.52 µs / 8.25 µs / 10.5 µs / 6.84 µs 8.41 µs / 9.47 µs / 18.4 µs / 7.83 µs - / - / - / - 9.17 µs / 10.3 µs / 11.2 µs / 6.39 µs 18.8 µs / 27.5 µs / 41.1 µs / 23.8 µs 41.8 µs / 66.9 µs / 65.9 µs / 27.8 µs 12.7 µs / 14.8 µs / 17.9 µs / 9.29 µs
ML-KEM-768 decapsulate 4.61 µs / 5.75 µs / 7.03 µs / 4.13 µs 8.79 µs / 11.2 µs / 15.9 µs / 7.60 µs - / - / - / - 6.52 µs / 7.23 µs / 7.40 µs / 4.03 µs 15.8 µs / 22.4 µs / 31.6 µs / 24.5 µs 54.6 µs / 86.8 µs / 82.8 µs / 34.0 µs 13.4 µs / 15.5 µs / 18.9 µs / 9.44 µs
P-384 ECDH 98.2 µs / 130 µs / 150 µs / 91.1 µs 111 µs / 145 µs / 175 µs / 104 µs 370 µs / 581 µs / 636 µs / 411 µs 170 µs / 207 µs / 239 µs / 152 µs 261 µs / 458 µs / 484 µs / 280 µs 393 µs / 746 µs / 761 µs / 492 µs - / - / - / -
P-384 ECDSA sign 23.8 µs / 31.9 µs / 39.0 µs / 22.5 µs 45.8 µs / 64.7 µs / 82.2 µs / 49.5 µs 197 µs / 313 µs / 341 µs / 223 µs 90.4 µs / 110 µs / 129 µs / 80.6 µs 88.9 µs / 152 µs / 163 µs / 103 µs 85.8 µs / 164 µs / 168 µs / 112 µs - / - / - / -
P-384 ECDSA verify 98.6 µs / 120 µs / 141 µs / 84.7 µs 114 µs / 152 µs / 175 µs / 111 µs 360 µs / 567 µs / 617 µs / 403 µs 166 µs / 204 µs / 238 µs / 150 µs 215 µs / 370 µs / 397 µs / 238 µs 351 µs / 658 µs / 685 µs / 424 µs - / - / - / -
P-521 ECDH 161 µs / 222 µs / 217 µs / 130 µs 168 µs / 236 µs / 245 µs / 142 µs - / - / - / - - / - / - / - 272 µs / 391 µs / 466 µs / 246 µs 437 µs / 600 µs / 779 µs / 397 µs - / - / - / -
P-521 ECDSA sign 39.8 µs / 55.5 µs / 64.1 µs / 36.5 µs 87.9 µs / 127 µs / 156 µs / 84.0 µs - / - / - / - - / - / - / - 130 µs / 187 µs / 220 µs / 133 µs 94.3 µs / 144 µs / 184 µs / 79.8 µs - / - / - / -
P-521 ECDSA verify 145 µs / 193 µs / 204 µs / 120 µs 187 µs / 259 µs / 283 µs / 166 µs - / - / - / - - / - / - / - 261 µs / 379 µs / 449 µs / 253 µs 354 µs / 481 µs / 627 µs / 251 µs - / - / - / -

Criterion's estimates from rind's benchmark report at ccdda859, run 2026-11-09, as Arrow Lake / Zen 3 / Coffee Lake / Apple M4. Every library runs its native path on each CPU. On Mac, rind holds DIT across the timed loop, as a caller batching calls does.

AI is really fucking good at benchmarks. Moments like this fill me with dread as a professional software engineer.

A decade ago, I wasted weeks speeding up Go’s crypto. I was that guy, hand-writing assembly to use the PCLMULQDQ instruction for massive performance gains (AES-GCM). It didn’t even get merged because I insisted on trying to change the Go API like an idiot.

I should have just waited a decade for Opus 5.5 instead. idiot.

Lean into Lean #

But does it actually work? How can we build confidence?

I saw an Anthropic blog post about formal verification. Like most programmers, I don’t even test my code, let alone formally verify it. But I figured I’d play along and waste a few more tokens chasing the dragon.

Because like, if you can prove the vibe slop is correct, it’s no longer vibe slop right?

Almost nobody proves

their crypto

Squares: Arrow Lake, Zen 3, Coffee Lake, Apple M4. Blank: not offered.

Data #

Primitive rind aws-lc-rs ring RustCrypto graviola libcrux OpenSSL
AES-GCM Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven end to end, Apple M4: unproven · x86_64: Vale's F* AES-GCM, for every message without VAES but only short ones with it Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: unproven · x86_64: aws-lc-verification's SAW AES-GCM, for AES-256 only Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven
ChaCha20-Poly1305 Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: proven end to end, Zen 3: proven end to end, Coffee Lake: proven end to end, Apple M4: proven end to end Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven
XChaCha20-Poly1305 Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: proven core · x86_64: HACL*'s F* ChaCha20-Poly1305, under an unverified HChaCha20 ·aarch64: HACL*'s F* ChaCha20-Poly1305, under an unverified HChaCha20
AES header protection Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: unproven · x86_64: aws-lc-verification's SAW AES block, for AES-256 only Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven
ChaCha20 header protection Arrow Lake: proven end to end, Zen 3: proven end to end, Coffee Lake: proven end to end, Apple M4: proven end to end Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven
SHA-256 Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: proven end to end, Zen 3: proven end to end, Coffee Lake: proven end to end, Apple M4: proven end to end Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven
SHA-512 Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: proven end to end, Zen 3: unproven, Coffee Lake: proven end to end, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: proven end to end, Zen 3: proven end to end, Coffee Lake: proven end to end, Apple M4: proven end to end Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven
HMAC-SHA256 Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: proven end to end, Zen 3: proven end to end, Coffee Lake: proven end to end, Apple M4: proven end to end Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven
HKDF-SHA256 Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: proven end to end, Zen 3: proven end to end, Coffee Lake: proven end to end, Apple M4: proven end to end Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven
X25519 Arrow Lake: proven end to end, Zen 3: proven end to end, Coffee Lake: proven end to end, Apple M4: proven end to end Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: proven core · x86_64: s2n-bignum's HOL Light X25519 ladder ·aarch64: s2n-bignum's HOL Light X25519 ladder Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: proven core · x86_64: s2n-bignum's HOL Light X25519 ladder ·aarch64: s2n-bignum's HOL Light X25519 ladder Arrow Lake: proven end to end, Zen 3: proven end to end, Coffee Lake: proven end to end, Apple M4: proven end to end Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven
Ed25519 Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: proven core · x86_64: s2n-bignum's HOL Light scalar multiplications ·aarch64: s2n-bignum's HOL Light scalar multiplications Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: proven core · x86_64: s2n-bignum's HOL Light scalar multiplications ·aarch64: s2n-bignum's HOL Light scalar multiplications Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: proven core · x86_64: s2n-bignum's HOL Light scalar multiplications ·aarch64: s2n-bignum's HOL Light scalar multiplications Arrow Lake: proven end to end, Zen 3: proven end to end, Coffee Lake: proven end to end, Apple M4: proven end to end Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven
P-256 Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: proven end to end · x86_64: s2n-bignum's HOL Light scalar multiplication, for ECDH Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: proven core · x86_64: s2n-bignum's HOL Light scalar multiplication, for ECDH ·aarch64: s2n-bignum's HOL Light scalar multiplication, for ECDH Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: proven end to end, Zen 3: proven end to end, Coffee Lake: proven end to end, Apple M4: proven end to end Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven
P-384 Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: proven core · x86_64: s2n-bignum's HOL Light scalar multiplication, for ECDH ·aarch64: s2n-bignum's HOL Light scalar multiplication, for ECDH Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: proven core · x86_64: s2n-bignum's HOL Light scalar multiplication, for ECDH ·aarch64: s2n-bignum's HOL Light scalar multiplication, for ECDH Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven
P-521 Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: proven core · x86_64: s2n-bignum's HOL Light scalar multiplication, for ECDH ·aarch64: s2n-bignum's HOL Light scalar multiplication, for ECDH Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: proven core · x86_64: s2n-bignum's HOL Light scalar multiplication, for ECDH ·aarch64: s2n-bignum's HOL Light scalar multiplication, for ECDH Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven
RSA-2048 PSS Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: proven end to end, Zen 3: proven end to end, Coffee Lake: proven end to end, Apple M4: proven end to end Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven
RSA-2048 PKCS#1 Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven
ML-KEM-768 Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: proven core · x86_64: s2n-bignum's and mlkem-native's HOL Light NTT and sampling ·aarch64: s2n-bignum's HOL Light NTT and sampling Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: proven core · x86_64: mlkem-native's HOL Light AVX2 NTT and sampling ·aarch64: mlkem-native's HOL Light aarch64 NTT and sampling Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: proven core, Zen 3: proven core, Coffee Lake: proven core, Apple M4: proven core · x86_64: s2n-bignum's HOL Light NTT and base multiplication ·aarch64: s2n-bignum's HOL Light NTT and base multiplication Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven Arrow Lake: unproven, Zen 3: unproven, Coffee Lake: unproven, Apple M4: unproven

End to end: rind's benchmarks/verified.toml at ccdda859, whose ✓ needs a machine-checked proof of all the code, glue included. Proven core: a proven routine does the whole cipher, block function, scalar multiplication, or NTT for at least some of the row's operations; field arithmetic alone doesn't count. Checked against each library's source for each CPU's architecture, at the versions rind's report locks, run 2026-11-09.

Many of these implementations are faster AND formally verified. Including the afformentioned AES-GCM (the goat). At least according to Claude so grain of salt folks.

My goal is to get every algorithm formally proven. Claude says that will take years.

If only there was somebody in the audience works for a frontier lab and wants some easy marketting piece. Steal the glory from the cryptographers instead of the mathematicians.

Please Donate Tokens #

If it sounds like I’m desparate and begging for more tokens, ur right.

So I came up with a plan. I decided the best way to get tokens is to rage bait.

Bun is SUPER SLOW.

Holy shit it’s like REALLY SLOW.

Imagine doing super common stuff like TLS certificate generation in Bun.

Super SLOW.

faster than

stock Bun

Shorter is faster. Same Bun commit, with rind swapped in.

Data #

Operation Bun + rind Node Bun Deno
WebCrypto Ed25519 generateKey 6.18 µs 20.8 µs 9.71 µs 15.6 µs
WebCrypto Ed25519 importKey pkcs8 5.55 µs 18.6 µs 16.1 µs 6.20 µs
WebCrypto Ed25519 sign 7.73 µs 19.5 µs 12.1 µs 13.6 µs
WebCrypto Ed25519 verify 22.9 µs 50.0 µs 32.0 µs 26.4 µs
WebCrypto Ed25519 exportKey jwk 0.510 µs 1.48 µs 8.39 µs 8.30 µs
WebCrypto X25519 generateKey 4.58 µs 20.1 µs 9.50 µs 46.6 µs
WebCrypto X25519 deriveBits 18.1 µs 28.5 µs 22.5 µs 40.9 µs
WebCrypto P-256 generateKey 6.15 µs 19.3 µs 6.10 µs 22.8 µs
WebCrypto P-256 importKey pkcs8 9.86 µs 31.2 µs 9.84 µs 6.75 µs
WebCrypto P-256 importKey spki 1.05 µs 21.1 µs 1.04 µs 7.11 µs
WebCrypto P-256 sign 17.7 µs 31.5 µs 17.8 µs 356 µs
WebCrypto P-256 verify 33.2 µs 55.2 µs 33.2 µs 453 µs
WebCrypto P-256 exportKey pkcs8 3.45 µs 12.0 µs 3.41 µs 3.54 µs
WebCrypto P-256 ECDH deriveBits 31.5 µs 38.6 µs 31.6 µs 444 µs
WebCrypto P-384 generateKey 26.4 µs 76.4 µs 203 µs 47.9 µs
WebCrypto P-384 importKey pkcs8 21.9 µs 121 µs 405 µs 7.37 µs
WebCrypto P-384 importKey spki 1.56 µs 52.8 µs 1.21 µs 7.39 µs
WebCrypto P-384 sign 27.4 µs 127 µs 241 µs 955 µs
WebCrypto P-384 verify 97.0 µs 237 µs 246 µs 1.23 ms
WebCrypto P-384 exportKey pkcs8 0.480 µs 21.1 µs 16.8 µs 3.36 µs
WebCrypto P-384 ECDH deriveBits 84.7 µs 164 µs 221 µs 1.23 ms
WebCrypto P-521 generateKey 41.5 µs 81.5 µs 491 µs 480 µs
WebCrypto P-521 importKey pkcs8 36.6 µs 125 µs 982 µs 7.19 µs
WebCrypto P-521 importKey spki 1.56 µs 53.0 µs 1.63 µs 7.63 µs
WebCrypto P-521 sign 44.4 µs 165 µs 585 µs 1.38 ms
WebCrypto P-521 verify 142 µs 283 µs 607 µs 1.72 ms
WebCrypto P-521 exportKey pkcs8 0.480 µs 20.0 µs 44.2 µs 3.84 µs
WebCrypto P-521 ECDH deriveBits 127 µs 172 µs 537 µs 1.63 ms
node:crypto Ed25519 generateKeyPairSync 5.12 µs 15.9 µs 9.39 µs 12.2 µs
node:crypto Ed25519 sign 4.54 µs 14.9 µs 8.63 µs 9.57 µs
node:crypto Ed25519 verify 19.6 µs 45.8 µs 28.4 µs 22.0 µs
node:crypto Ed25519 sign, PEM key each call 9.21 µs 36.0 µs 17.1 µs 22.6 µs
node:crypto X25519 generateKeyPairSync 5.02 µs 14.8 µs 9.24 µs 11.8 µs
node:crypto X25519 diffieHellman 14.3 µs 20.9 µs 19.1 µs 36.0 µs
node:crypto P-256 generateKeyPairSync 5.83 µs 13.2 µs 5.80 µs 141 µs
node:crypto P-256 sign 14.0 µs 15.4 µs 14.0 µs 305 µs
node:crypto P-256 verify 29.5 µs 40.0 µs 29.6 µs 294 µs
node:crypto P-256 createPrivateKey pem 6.07 µs 12.1 µs 5.53 µs 144 µs
node:crypto P-256 export pkcs8 pem 3.82 µs 11.0 µs 3.82 µs 143 µs
node:crypto P-256 diffieHellman 27.8 µs 32.6 µs 27.7 µs 141 µs
node:crypto P-256 ECDH computeSecret 31.9 µs 61.0 µs 31.8 µs 282 µs
node:crypto P-384 generateKeyPairSync 21.4 µs 67.8 µs 203 µs 355 µs
node:crypto P-384 sign 23.7 µs 91.9 µs 235 µs 742 µs
node:crypto P-384 verify 93.3 µs 201 µs 238 µs 711 µs
node:crypto P-384 createPrivateKey pem 22.0 µs 14.9 µs 204 µs 358 µs
node:crypto P-384 export pkcs8 pem 0.780 µs 20.2 µs 17.2 µs 357 µs
node:crypto P-384 diffieHellman 81.1 µs 158 µs 217 µs 355 µs
node:crypto P-384 ECDH computeSecret 81.0 µs 284 µs 418 µs 708 µs
node:crypto P-521 generateKeyPairSync 36.6 µs 74.2 µs 491 µs 443 µs
node:crypto P-521 sign 40.2 µs 131 µs 577 µs 972 µs
node:crypto P-521 verify 138 µs 249 µs 591 µs 933 µs
node:crypto P-521 createPrivateKey pem 37.6 µs 15.3 µs 493 µs 427 µs
node:crypto P-521 export pkcs8 pem 0.900 µs 19.3 µs 44.9 µs 425 µs
node:crypto P-521 diffieHellman 125 µs 164 µs 534 µs 422 µs
node:crypto P-521 ECDH computeSecret 125 µs 296 µs 1.02 ms -

Core Ultra 7 270K Plus, one pinned core, the median of 5 alternating rounds, 2026-11-07. Bun + rind: bun 1.4.4 (fb621aaac); Node: node v24.21.0; Bun: bun 1.4.4 (b1007f117); Deno: deno 2.9.8. Bun and Bun + rind are release builds of the same Bun commit, without and with the rind prototype, which moves Ed25519, X25519, P-384, and P-521 onto rind; P-256 still runs BoringSSL in both.

I threw Deprecated Deno in just because it uses RustCrypto. Oh man, I used to hate RustCrypto back when I was a programmer. Do not use it, even though they registered official sounding crates like aes and rsa.

Anyway, back to dunking on JS runtimes for being slow at things they weren’t designed to do, like cryptography:

calls where Bun + rind is fastest,

or within 10%

Blank: the runtime refuses it. P-256 runs BoringSSL in both Buns.

Data #

Operation Bun + rind Node Bun Deno
WebCrypto Ed25519 generateKey 6.18 µs 20.8 µs 9.71 µs 15.6 µs
WebCrypto Ed25519 importKey pkcs8 5.55 µs 18.6 µs 16.1 µs 6.20 µs
WebCrypto Ed25519 sign 7.73 µs 19.5 µs 12.1 µs 13.6 µs
WebCrypto Ed25519 verify 22.9 µs 50.0 µs 32.0 µs 26.4 µs
WebCrypto Ed25519 exportKey jwk 0.510 µs 1.48 µs 8.39 µs 8.30 µs
WebCrypto X25519 generateKey 4.58 µs 20.1 µs 9.50 µs 46.6 µs
WebCrypto X25519 deriveBits 18.1 µs 28.5 µs 22.5 µs 40.9 µs
WebCrypto P-256 generateKey 6.15 µs 19.3 µs 6.10 µs 22.8 µs
WebCrypto P-256 importKey pkcs8 9.86 µs 31.2 µs 9.84 µs 6.75 µs
WebCrypto P-256 importKey spki 1.05 µs 21.1 µs 1.04 µs 7.11 µs
WebCrypto P-256 sign 17.7 µs 31.5 µs 17.8 µs 356 µs
WebCrypto P-256 verify 33.2 µs 55.2 µs 33.2 µs 453 µs
WebCrypto P-256 exportKey pkcs8 3.45 µs 12.0 µs 3.41 µs 3.54 µs
WebCrypto P-256 ECDH deriveBits 31.5 µs 38.6 µs 31.6 µs 444 µs
WebCrypto P-384 generateKey 26.4 µs 76.4 µs 203 µs 47.9 µs
WebCrypto P-384 importKey pkcs8 21.9 µs 121 µs 405 µs 7.37 µs
WebCrypto P-384 importKey spki 1.56 µs 52.8 µs 1.21 µs 7.39 µs
WebCrypto P-384 sign 27.4 µs 127 µs 241 µs 955 µs
WebCrypto P-384 verify 97.0 µs 237 µs 246 µs 1.23 ms
WebCrypto P-384 exportKey pkcs8 0.480 µs 21.1 µs 16.8 µs 3.36 µs
WebCrypto P-384 ECDH deriveBits 84.7 µs 164 µs 221 µs 1.23 ms
WebCrypto P-521 generateKey 41.5 µs 81.5 µs 491 µs 480 µs
WebCrypto P-521 importKey pkcs8 36.6 µs 125 µs 982 µs 7.19 µs
WebCrypto P-521 importKey spki 1.56 µs 53.0 µs 1.63 µs 7.63 µs
WebCrypto P-521 sign 44.4 µs 165 µs 585 µs 1.38 ms
WebCrypto P-521 verify 142 µs 283 µs 607 µs 1.72 ms
WebCrypto P-521 exportKey pkcs8 0.480 µs 20.0 µs 44.2 µs 3.84 µs
WebCrypto P-521 ECDH deriveBits 127 µs 172 µs 537 µs 1.63 ms
node:crypto Ed25519 generateKeyPairSync 5.12 µs 15.9 µs 9.39 µs 12.2 µs
node:crypto Ed25519 sign 4.54 µs 14.9 µs 8.63 µs 9.57 µs
node:crypto Ed25519 verify 19.6 µs 45.8 µs 28.4 µs 22.0 µs
node:crypto Ed25519 sign, PEM key each call 9.21 µs 36.0 µs 17.1 µs 22.6 µs
node:crypto X25519 generateKeyPairSync 5.02 µs 14.8 µs 9.24 µs 11.8 µs
node:crypto X25519 diffieHellman 14.3 µs 20.9 µs 19.1 µs 36.0 µs
node:crypto P-256 generateKeyPairSync 5.83 µs 13.2 µs 5.80 µs 141 µs
node:crypto P-256 sign 14.0 µs 15.4 µs 14.0 µs 305 µs
node:crypto P-256 verify 29.5 µs 40.0 µs 29.6 µs 294 µs
node:crypto P-256 createPrivateKey pem 6.07 µs 12.1 µs 5.53 µs 144 µs
node:crypto P-256 export pkcs8 pem 3.82 µs 11.0 µs 3.82 µs 143 µs
node:crypto P-256 diffieHellman 27.8 µs 32.6 µs 27.7 µs 141 µs
node:crypto P-256 ECDH computeSecret 31.9 µs 61.0 µs 31.8 µs 282 µs
node:crypto P-384 generateKeyPairSync 21.4 µs 67.8 µs 203 µs 355 µs
node:crypto P-384 sign 23.7 µs 91.9 µs 235 µs 742 µs
node:crypto P-384 verify 93.3 µs 201 µs 238 µs 711 µs
node:crypto P-384 createPrivateKey pem 22.0 µs 14.9 µs 204 µs 358 µs
node:crypto P-384 export pkcs8 pem 0.780 µs 20.2 µs 17.2 µs 357 µs
node:crypto P-384 diffieHellman 81.1 µs 158 µs 217 µs 355 µs
node:crypto P-384 ECDH computeSecret 81.0 µs 284 µs 418 µs 708 µs
node:crypto P-521 generateKeyPairSync 36.6 µs 74.2 µs 491 µs 443 µs
node:crypto P-521 sign 40.2 µs 131 µs 577 µs 972 µs
node:crypto P-521 verify 138 µs 249 µs 591 µs 933 µs
node:crypto P-521 createPrivateKey pem 37.6 µs 15.3 µs 493 µs 427 µs
node:crypto P-521 export pkcs8 pem 0.900 µs 19.3 µs 44.9 µs 425 µs
node:crypto P-521 diffieHellman 125 µs 164 µs 534 µs 422 µs
node:crypto P-521 ECDH computeSecret 125 µs 296 µs 1.02 ms -

Core Ultra 7 270K Plus, one pinned core, the median of 5 alternating rounds, 2026-11-07. Bun + rind: bun 1.4.4 (fb621aaac); Node: node v24.21.0; Bun: bun 1.4.4 (b1007f117); Deno: deno 2.9.8. Bun and Bun + rind are release builds of the same Bun commit, without and with the rind prototype, which moves Ed25519, X25519, P-384, and P-521 onto rind; P-256 still runs BoringSSL in both.

Did the rage bait work? Login to your work account, choose the unreleased model, then /quest-spawn to work on the backlog I planned.

k thx

try it? #

Up to you, it depends on your tolerance for vibe slop. This is cryptography so it’s dangerous to get wrong.

But as Sun Tzu once said: yolo

rind = "0.3"

ring = { package = "rind-ring", version = "0.17" }

rustls = { version = "0.23", default-features = false, features = ["std", "tls12"] }
rind-rustls = "0.23"

aws-lc-rs = { package = "rind-aws-lc-rs", version = "1" }

There’s other adapters too if you’re lazy. Or just tell Mr AI to migrate to the rind API.

The Bill #

All of this crypto jizz, it must have been expensive, right?

This took my 9-year old desktop PC… 12 days. And much of that was waiting for a usage reset.

The total was about $4.2k at API pricing. But API pricing is a meme.

12 DAYS · TERMINAL /goal

Data #

Line Amount
Claude Opus 5.5 $4,158
Tokens 10.30B
Cache reads 98%
Agent hrs 559.4
Human hrs 28.3
List price $4,158.00
Paid $40.00

From the final tally in moq-dev/rind#499, through November 7, 2026, at 14:32 PT. Sessions working in a rind checkout, or whose task names moq-dev/rind, from the graviola bootstrap on 2026-10-27. Opus usage from Claude Code logs, each API message counted once, priced at its standard API rate. Paid: 12 days of a $100 a month plan. Human hours are the maintainer's prompts, with gaps over 15 minutes counted as away. Agent hours cover Claude Code sessions.

That’s right, my credit card made the internet a better place* for $40. It’s ridiculous.

  • Assuming anybody actually uses this library.

FIN #

Real talk: Programming is dead. We had a good run.

Many of these crypto libraries have been hand optimized by some of the smartest people I know (cryptography nerds). And they get completely blown out of the water by a vibe coder.

I know we still need humans to tell the AI to do dumb shit. Like to rewrite libraries in Rust. I know that AI is still terrible at anything involving user experience.

But like, for how much longer?

── more in #artificial-intelligence 4 stories · sorted by recency
── more on @rind 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/vibe-slopped-cryptog…] indexed:0 read:59min 2026-11-09 · —