diff --git a/public/blog/rind/cover.svg b/public/blog/rind/cover.svg new file mode 100644 index 0000000..d249b85 --- /dev/null +++ b/public/blog/rind/cover.svg @@ -0,0 +1,31 @@ + + + rind + A curled strip of green graviola peel forms the r, with white ind starting beneath the curl and extending to the right. + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/blog/rind/rind.svg b/public/blog/rind/rind.svg new file mode 100644 index 0000000..b49acd5 --- /dev/null +++ b/public/blog/rind/rind.svg @@ -0,0 +1,29 @@ + + rind + A curled strip of green graviola peel forms the r, with white ind starting beneath the curl and extending to the right. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/blog/rind/tired.webm b/public/blog/rind/tired.webm new file mode 100644 index 0000000..551ca5c Binary files /dev/null and b/public/blog/rind/tired.webm differ diff --git a/src/components/rind/build.tsx b/src/components/rind/build.tsx new file mode 100644 index 0000000..995eb97 --- /dev/null +++ b/src/components/rind/build.tsx @@ -0,0 +1,134 @@ +// What rustls costs to build from scratch on each crypto library: a race, in seconds averaged over every CPU. +import { createSignal, For, onCleanup, onMount } from "solid-js"; +import { commit, cpu, day, Figure, frames, geomean, midscreen, name, reduced } from "./chart"; +import data from "./data/build.json"; + +const RACERS = ["rustls-rind", "rustls-ring", "rustls-aws-lc-rs"]; +// Race seconds per real second. +const SPEED = 12; + +const TOOLS: Record = { cc: "C compiler", make: "make", perl: "perl", "pkg-config": "pkg-config" }; +const needs = (tools: string[]) => + tools.length ? `needs ${tools.map((t) => TOOLS[t] ?? t).join(", ")}` : "rustc only"; +const label = (build: string) => + build.startsWith("rustls-") ? `rustls + ${name(build.slice("rustls-".length))}` : name(build); + +type Host = (typeof data.hosts)[number]; +const seconds = (h: Host, build: string) => { + const b = h.builds.find((b) => b.name === build); + if (!b) throw new Error(`build.json's ${h.name} has no ${build}`); + return b; +}; + +export default function Build() { + // Each racer's build, its time the geometric mean over every CPU. + const racers = RACERS.map((r) => { + const builds = data.hosts.map((h) => seconds(h, r)); + const tools = builds[0].tools; + if (builds.some((b) => b.tools.join() !== tools.join())) throw new Error(`${r} needs different tools per CPU`); + return { name: r, seconds: geomean(builds.map((b) => b.seconds)), tools }; + }); + const max = Math.max(...racers.map((r) => r.seconds)); + const time = (r: string) => { + const racer = racers.find((x) => x.name === r); + if (!racer) throw new Error(`${r} isn't racing`); + return racer.seconds; + }; + const ratio = (x: Host) => seconds(x, "rustls-aws-lc-rs").seconds / seconds(x, "rustls-rind").seconds; + + // The race clock rests at the finish, so the figure reads complete before it plays. + const [clock, setClock] = createSignal(max); + let figure: HTMLElement | undefined; + let cancel = () => {}; + const race = () => { + cancel(); + setClock(0); + cancel = frames((s) => { + setClock(Math.min(max, s * SPEED)); + return s * SPEED < max; + }); + }; + onMount(() => { + if (figure && !reduced()) midscreen(figure, race); + }); + onCleanup(() => cancel()); + + return ( +
{ + figure = el; + }} + kicker={`rustls, cold release build · averaged over ${data.hosts.length} CPUs`} + number={`${(time("rustls-aws-lc-rs") / time("rustls-rind")).toFixed(1)}×`} + headline={ + <> + faster to +
+ build + + } + label={`Seconds to build rustls on rind, ring, and aws-lc-rs, averaged over ${data.hosts.length} CPUs, as a race.`} + table={{ + head: ["CPU", "Build", "Time", "CPU time", "Binary", "Tools"], + rows: data.hosts.flatMap((x) => + x.builds.map((b) => [ + x.name, + label(b.name), + `${b.seconds.toFixed(1)} s`, + `${b.cpu_seconds.toFixed(1)} s`, + `${(b.bytes / 1024 / 1024).toFixed(2)} MiB`, + needs(b.tools), + ]), + ), + }} + source={ + <> + rind's admin/build-cost: the median of cold builds with an empty target directory and a warm download cache.{" "} + {data.hosts.map((x, i) => ( + <> + {i ? "; " : ""} + {x.name}: {cpu(x.source.cpu)}, {x.source.jobs} jobs, {x.source.runs} runs, {day(x.source.date)}, at{" "} + {commit(x.source.rind)} + + ))} + . A tool counts when the build fails without it. + + } + > +
+
+
+ {clock().toFixed(1)} srace clock, {SPEED}× speed +
+
+
+ + {(r) => { + const done = () => clock() >= r.seconds; + return ( +
+
+ {label(r.name)} +
+ {needs(r.tools)} +
+
+
+
{done() ? `${r.seconds.toFixed(1)} s ✓` : "compiling…"}
+
+
+ ); + }} + +
+
+

+ The geometric mean over CPUs. {data.hosts.map((x) => `${x.name}: ${ratio(x).toFixed(1)}×`).join(", ")}. +

+ +
+
+ ); +} diff --git a/src/components/rind/chart.css b/src/components/rind/chart.css new file mode 100644 index 0000000..f6b2632 --- /dev/null +++ b/src/components/rind/chart.css @@ -0,0 +1,499 @@ +/* The rind post's figures: one headline number each, dark like the rest of the site. */ +@import url("https://fonts.googleapis.com/css2?family=Big+Shoulders+Display:wght@700;900&display=swap"); + +.rind-fig { + --frame: #0f172a; + --frame-2: #131d33; + --line: rgb(148 163 184 / 16%); + --ink: #f1f5f9; + --ink-2: #94a3b8; + --ink-3: #64748b; + --rind: #22c55e; + --rind-2: #16a34a; + --rind-deep: #15803d; + --rival: #475569; + --rival-2: #334155; + --warn: #f59e0b; + --paper: #f4f4ef; + --paper-ink: #1c1917; + --display: "Big Shoulders Display", Impact, "Arial Narrow", sans-serif; + --mono: "JetBrains Mono", ui-monospace, Menlo, monospace; + + margin: 2rem 0; + padding: 1.75rem clamp(1.1rem, 4vw, 2.25rem); + border: 1px solid var(--line); + border-radius: 14px; + background: var(--frame); + color: var(--ink); + text-align: left; + overflow: hidden; +} +.rind-fig :focus-visible { + outline: 2px solid var(--rind); + outline-offset: 2px; +} +.rind-fig .kicker { + font-family: var(--mono); + font-size: 12px; + color: var(--ink-2); + text-transform: uppercase; + letter-spacing: 0.08em; +} +.rind-fig .hero { + display: flex; + flex-wrap: wrap; + align-items: flex-end; + gap: 6px 22px; +} +.rind-fig .big { + font-family: var(--display); + font-weight: 900; + line-height: 0.82; + letter-spacing: -0.01em; + font-variant-numeric: tabular-nums; +} +.rind-fig .number { + /* The line box is shorter than the digits, which rise 0.03em above it into the kicker */ + margin-top: 0.12em; + font-size: clamp(84px, 18vw, 140px); + color: var(--rind); +} +/* Shrunk and raised to span the digits, baseline to top, rather than dip 0.2em below them */ +.rind-fig .number .slash { + font-size: 0.8em; + vertical-align: 0.2em; +} +.rind-fig .headline { + margin: 6px 0 0; + font-family: var(--display); + font-weight: 700; + font-size: clamp(26px, 5vw, 36px); + line-height: 1; + text-transform: uppercase; + text-wrap: balance; +} +.rind-fig .fine { + margin: 16px 0 0; + font-family: var(--mono); + font-size: 11.5px; + line-height: 1.5; + color: var(--ink-3); +} +.rind-fig .data { + margin-top: 14px; + font-size: 12px; + color: var(--ink-2); +} +.rind-fig .data summary { + cursor: pointer; + font-family: var(--mono); + color: var(--ink-3); +} +.rind-fig .data table { + width: 100%; + margin-top: 8px; + text-align: left; + font-variant-numeric: tabular-nums; +} +.rind-fig .data th, +.rind-fig .data td { + padding: 3px 12px 3px 0; + text-align: left; +} +.rind-fig .data tbody tr { + border-top: 1px solid var(--line); +} +.rind-fig .data p { + margin: 8px 0 0; + font-size: 11px; + color: var(--ink-3); +} +.rind-fig a { + text-decoration: underline; +} + +/* QUIC: ping-pong lanes and the per-CPU scoreboard */ +.rind-fig .lanes { + display: grid; + gap: 8px; + margin-top: 26px; +} +.rind-fig .lane { + display: grid; + grid-template-columns: 96px minmax(0, 1fr) 44px; + gap: 12px; + align-items: center; +} +.rind-fig .lane .who { + font-family: var(--mono); + font-size: 12.5px; + line-height: 1.2; + text-align: right; +} +.rind-fig .lane .who small { + display: block; + font-size: 10.5px; + color: var(--ink-3); +} +.rind-fig .lane canvas { + display: block; + width: 100%; + height: 34px; + border: 1px solid var(--line); + border-radius: 7px; + background: var(--frame-2); +} +.rind-fig .lane .count { + font-family: var(--display); + font-weight: 900; + font-size: 26px; + line-height: 1; + font-variant-numeric: tabular-nums; + color: var(--ink-2); +} +.rind-fig .lane.me .who, +.rind-fig .lane.me .count { + color: var(--rind); + font-weight: 700; +} +.rind-fig .lane.me canvas { + border-color: rgb(34 197 94 / 40%); +} +/* Bars: runtimes and the build race */ +.rind-fig .bars { + display: grid; + gap: 10px; + margin-top: 26px; +} +.rind-fig .bar { + display: grid; + grid-template-columns: 112px minmax(0, 1fr) 96px; + gap: 14px; + align-items: center; +} +.rind-fig .bar .name { + font-family: var(--mono); + font-size: 13px; + line-height: 1.25; + text-align: right; + color: var(--ink-2); +} +.rind-fig .bar .track { + position: relative; + height: 30px; +} +.rind-fig .bar .fill { + position: absolute; + inset: 0 auto 0 0; + border-radius: 0 6px 6px 0; + background: var(--rival); + transition: width 1.2s cubic-bezier(0.2, 0.8, 0.2, 1); +} +.rind-fig .bar .val { + font-family: var(--mono); + font-size: 12.5px; + color: var(--ink-3); + font-variant-numeric: tabular-nums; +} +.rind-fig .bar.me .name, +.rind-fig .bar.me .val { + color: var(--rind); + font-weight: 700; +} +.rind-fig .bar.me .fill { + background: var(--rind); +} +.rind-fig .race .bar { + grid-template-columns: 150px minmax(0, 1fr); +} +.rind-fig .race .track { + height: 40px; + border: 1px solid var(--line); + border-radius: 6px; + background: var(--frame-2); + overflow: hidden; +} +.rind-fig .race .go { + position: absolute; + inset: 0 auto 0 0; + background: repeating-linear-gradient(-45deg, var(--rival) 0 8px, var(--rival-2) 8px 16px); +} +.rind-fig .race .me .go { + background: repeating-linear-gradient(-45deg, var(--rind) 0 8px, var(--rind-2) 8px 16px); +} +.rind-fig .race .done .go { + background: var(--rival); +} +.rind-fig .race .me.done .go { + background: var(--rind); +} +.rind-fig .race .time { + position: absolute; + top: 50%; + right: 10px; + transform: translateY(-50%); + font-family: var(--mono); + font-size: 13px; + font-weight: 700; + font-variant-numeric: tabular-nums; +} +.rind-fig .race-head { + display: flex; + flex-wrap: wrap; + align-items: flex-end; + justify-content: space-between; + gap: 16px; +} +.rind-fig .clock { + font-family: var(--mono); + font-size: 13px; + text-align: right; + color: var(--ink-2); +} +.rind-fig .clock strong { + display: block; + font-family: var(--display); + font-weight: 900; + font-size: 58px; + line-height: 0.9; + color: var(--ink); + font-variant-numeric: tabular-nums; +} +.rind-fig .chip { + display: inline-block; + margin-top: 3px; + padding: 1px 6px; + border: 1px solid rgb(245 158 11 / 45%); + border-radius: 3px; + font-size: 10.5px; + font-weight: 500; + color: var(--warn); +} +.rind-fig .chip.ok { + border-color: rgb(34 197 94 / 45%); + color: var(--rind); +} +.rind-fig .replay { + padding: 6px 12px; + border: 1px solid var(--line); + border-radius: 6px; + background: var(--frame-2); + font: 500 12px var(--mono); + color: var(--ink); + cursor: pointer; +} +.rind-fig .replay:hover { + border-color: var(--rind); +} + +/* Coverage heatmap */ +.rind-fig .scroll { + margin-top: 22px; + overflow-x: auto; +} +.rind-fig .heat { + display: grid; + grid-template-columns: auto repeat(var(--libs), 54px); + justify-content: start; + align-items: center; + min-width: 560px; +} +.rind-fig .heat > div { + padding-block: 3px; +} +.rind-fig .heat .row { + padding-right: 10px; + font-family: var(--mono); + font-size: 11px; + text-align: right; + white-space: nowrap; + color: var(--ink-2); +} +.rind-fig .heat .lib { + display: flex; + justify-content: center; + padding-bottom: 8px; + font-family: var(--mono); + font-size: 9px; + letter-spacing: -0.02em; /* so "RustCrypto" fits its column unbroken */ + white-space: nowrap; + color: var(--ink-2); +} +.rind-fig .heat .me { + background: rgb(34 197 94 / 7%); +} +.rind-fig .heat .lib.me { + font-size: 12px; + font-weight: 700; + color: var(--rind); +} +.rind-fig .heat .cell { + display: flex; + justify-content: center; +} +.rind-fig .trio { + display: inline-flex; + gap: 2px; +} +.rind-fig .trio i { + display: block; + width: 11px; + height: 11px; + border-radius: 3px; +} +.rind-fig .trio .e2e { + background: var(--rind); + box-shadow: 0 0 8px rgb(34 197 94 / 50%); +} +.rind-fig .trio .routine { + border: 1.5px dashed var(--rind); +} +.rind-fig .trio .none { + background: var(--rival-2); +} +.rind-fig .heat .section { + grid-column: 1 / -1; + padding-top: 14px; + font-family: var(--display); + font-size: 15px; + font-weight: 800; + letter-spacing: 0.04em; + text-transform: uppercase; + color: var(--ink); +} +.rind-fig .heat.runtimes { + grid-template-columns: auto repeat(4, 104px); +} +.rind-fig .heat.runtimes .lib:not(.me) { + font-size: 11px; +} +.rind-fig .tile { + display: block; + width: 92px; + padding-block: 2px; + border-radius: 4px; + font-family: var(--mono); + font-size: 11px; + font-weight: 600; + text-align: center; + color: var(--frame); +} +/* Speed bands, green at fastest to red at over 8×. */ +.rind-fig .s0 { + background: #22c55e; +} +.rind-fig .s1 { + background: #84cc16; +} +.rind-fig .s2 { + background: #eab308; +} +.rind-fig .s3 { + background: #f59e0b; +} +.rind-fig .s4 { + background: #f97316; +} +.rind-fig .s5 { + background: #ef4444; +} +.rind-fig .s6 { + background: #b91c1c; +} +.rind-fig .tile.s5, +.rind-fig .tile.s6 { + color: var(--ink); +} +.rind-fig .key { + display: flex; + flex-wrap: wrap; + gap: 6px 18px; + margin-top: 14px; + font-size: 12px; + color: var(--ink-2); +} +.rind-fig .key span { + display: flex; + align-items: center; + gap: 6px; +} + +/* Tally receipt */ +.rind-fig .till { + display: grid; + place-items: center; + padding-block: 8px 12px; +} +.rind-fig .receipt { + --z: 8px; + width: 100%; + max-width: 320px; + padding: 22px 20px 30px; + background: var(--paper); + color: var(--paper-ink); + font-family: var(--mono); + font-size: 12px; + line-height: 1.6; + transform: rotate(1.6deg); + box-shadow: 0 18px 40px rgb(0 0 0 / 45%); + mask: conic-gradient(from -45deg at bottom, #0000, #000 1deg 89deg, #0000 90deg) 50% / calc(2 * var(--z)) 100%; +} +.rind-fig .receipt .c { + text-align: center; +} +.rind-fig .receipt .store { + font-family: var(--display); + font-weight: 900; + font-size: 34px; + line-height: 1; + letter-spacing: 0.06em; +} +.rind-fig .receipt hr { + margin: 10px 0; + border: 0; + border-top: 1.5px dashed var(--paper-ink); + opacity: 0.5; +} +.rind-fig .receipt .li { + display: flex; + gap: 6px; +} +.rind-fig .receipt .li span:first-child { + flex: 1; + overflow: hidden; + white-space: nowrap; +} +.rind-fig .receipt .li span:first-child::after { + content: " ........................................"; +} +.rind-fig .receipt .list { + font-weight: 700; + font-size: 15px; +} +.rind-fig .receipt .list span:last-child { + text-decoration: line-through; + opacity: 0.6; +} +.rind-fig .receipt .paid { + font-weight: 700; + font-size: 20px; +} +.rind-fig .receipt .barcode { + height: 38px; + margin-top: 12px; + background: repeating-linear-gradient( + 90deg, + var(--paper-ink) 0 2px, + transparent 2px 4px, + var(--paper-ink) 4px 5px, + transparent 5px 8px, + var(--paper-ink) 8px 11px, + transparent 11px 12px + ); +} + +@media (prefers-reduced-motion: reduce) { + .rind-fig .bar .fill { + transition: none; + } +} diff --git a/src/components/rind/chart.tsx b/src/components/rind/chart.tsx new file mode 100644 index 0000000..6d68af1 --- /dev/null +++ b/src/components/rind/chart.tsx @@ -0,0 +1,156 @@ +// The frame every figure in the rind post shares: a kicker, one headline number, the plot, and the data +// behind it in a collapsed table with its source. +import { For, type JSX, onCleanup, Show } from "solid-js"; +import "./chart.css"; + +// A table cell: data, not JSX, so the frame builds each element once, in render order. An array is +// one cell of several parts. +type Part = string | { text: string; href: string }; +export type Cell = number | Part | Part[]; +const part = (p: Part) => (typeof p === "object" ? {p.text} : p); + +export interface Props { + kicker?: string; + number?: string; // the headline number, in giant type + headline?: JSX.Element; + label: string; // what the figure shows, for screen readers + table: { head: string[]; rows: Cell[][] }; + source: JSX.Element; + ref?: (el: HTMLElement) => void; + children: JSX.Element; +} + +export function Figure(props: Props) { + return ( +
+ +
{props.kicker}
+
+ {

{props.headline}

}
} + > +
+
+ {/* A fraction's slash dips below the digits into the headline, so it gets its own span */} + {props.number?.split("/").flatMap((p, i) => (i ? [/, p] : [p]))} +
+

{props.headline}

+
+ + {props.children} +
+ Data +
+ + + + {(h) => } + + + + + {(row) => ( + + + {(cell) => ( + + )} + + + )} + + +
{h}
{typeof cell === "number" ? cell : Array.isArray(cell) ? cell.map(part) : part(cell)}
+
+

{props.source}

+
+
+ ); +} + +export const reduced = () => matchMedia("(prefers-reduced-motion: reduce)").matches; + +// Runs `fn` once `el` reaches the middle half of the viewport, so an animation starts where it's seen. +export function midscreen(el: Element, fn: () => void) { + const observer = new IntersectionObserver( + (entries) => { + if (!entries[0].isIntersecting) return; + observer.disconnect(); + fn(); + }, + { rootMargin: "-25% 0px -25% 0px" }, + ); + observer.observe(el); + onCleanup(() => observer.disconnect()); +} + +// Calls `fn` with the seconds since start on every frame until it returns false; returns a cancel. +export function frames(fn: (seconds: number) => boolean) { + let id = 0; + let start: number | undefined; + const step = (now: number) => { + start ??= now; + if (fn((now - start) / 1000)) id = requestAnimationFrame(step); + }; + id = requestAnimationFrame(step); + return () => cancelAnimationFrame(id); +} + +// A CPU model as people say it: "Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz" is "Core i7-8700". +export const cpu = (model: string) => + model + .replace(/\((R|TM)\)/g, "") + .replace(/^(Intel|AMD)\s+/, "") + .replace(/\s+(CPU @.*|\d+-Core Processor)$/, "") + .trim(); + +export const geomean = (xs: number[]) => Math.exp(xs.reduce((a, x) => a + Math.log(x), 0) / xs.length); + +export function time(ns: number) { + if (ns < 1_000) return `${ns.toPrecision(3)} ns`; + if (ns < 1_000_000) return `${(ns / 1_000).toPrecision(3)} µs`; + return `${(ns / 1_000_000).toPrecision(3)} ms`; +} + +export const times = (x: number) => `${x.toFixed(2)}×`; + +// admin/bench-report's speed bands, by time over the fastest's; a heatmap colors each as .s. +const EDGES = [1.1, 1.25, 1.5, 2, 4, 8]; +export const BANDS = ["fastest, or within 10%", "to 1.25×", "to 1.5×", "to 2×", "to 4×", "to 8×", "over 8×"]; +export const band = (ratio: number) => { + const i = EDGES.findIndex((edge) => ratio <= edge); + return i < 0 ? EDGES.length : i; +}; + +// The speed key under a heatmap. +export function Bands() { + return ( +
+ + {(label, i) => ( + + + + + {label} + + )} + +
+ ); +} + +export const day = (iso: string) => iso.slice(0, 10); +// The days a set of hosts ran, since each host's report can come from a different run. +export const days = (hosts: { source: { date: string } }[]) => + [...new Set(hosts.map((h) => day(h.source.date)))].sort().join(" and "); + +export const commit = (sha: string) => {sha.slice(0, 8)}; + +// rind's report names for libraries, as the post spells them. +export const NAMES: Record = { + rustcrypto: "RustCrypto", + openssl: "OpenSSL", +}; +export const name = (lib: string) => NAMES[lib] ?? lib; diff --git a/src/components/rind/coverage.tsx b/src/components/rind/coverage.tsx new file mode 100644 index 0000000..61fe507 --- /dev/null +++ b/src/components/rind/coverage.tsx @@ -0,0 +1,112 @@ +// How much of each primitive every library proves, per CPU: end to end, a proven core under unproven glue, +// or nothing; blank where the library doesn't offer it. +import { For } from "solid-js"; +import { commit, days, Figure, name } from "./chart"; +import json from "./data/libraries.json"; + +type Status = "e2e" | "routine" | "none"; +const data = json as unknown as { + source: { rind: string; generated: string }; + libraries: string[]; + rows: string[]; + // By arch, then library, then row. + partial: Record>>; + hosts: { + name: string; + arch: string; + source: { date: string }; + coverage: Record>; + }[]; +}; +const arches = [...new Set(data.hosts.map((h) => h.arch))]; + +const WORDS: Record = { e2e: "proven end to end", routine: "proven core", none: "unproven" }; + +export default function Coverage() { + const statuses = (row: string, lib: string) => data.hosts.map((h) => h.coverage[row][lib]); + + return ( +
+ Almost nobody proves +
+ their crypto + + } + label="Which primitives each Rust crypto library proves, end to end or only at its core, on each CPU." + table={{ + head: ["Primitive", ...data.libraries.map(name)], + rows: data.rows.map((row) => [ + row, + ...data.libraries.map((lib) => { + const s = statuses(row, lib); + if (s.every((x) => x === null)) return ""; + const text = data.hosts.map((h, i) => `${h.name}: ${s[i] ? WORDS[s[i]] : "none"}`).join(", "); + return [ + text, + ...arches.flatMap((arch) => { + const partial = data.partial[arch][lib]?.[row]; + return partial ? [" · ", { text: `${arch}: ${partial.proof}`, href: partial.link }] : []; + }), + ]; + }), + ]), + }} + source={ + <> + End to end: rind's benchmarks/verified.toml at {commit(data.source.rind)}, 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{" "} + {days(data.hosts)}. + + } + > +
+
+
+ {(lib) =>
{name(lib)}
}
+ + {(row) => ( + <> +
{row}
+ + {(lib) => ( +
+ + {(s) => } + +
+ )} +
+ + )} +
+
+
+
+ + + + + proven end to end + + + + + + proven core, unproven glue + + + + + + unproven + +
+

Squares: {data.hosts.map((h) => h.name).join(", ")}. Blank: not offered.

+
+ ); +} diff --git a/src/components/rind/data/build.json b/src/components/rind/data/build.json new file mode 100644 index 0000000..207f698 --- /dev/null +++ b/src/components/rind/data/build.json @@ -0,0 +1,339 @@ +{ + "source": { + "rind": "00610affb74b8c64113c824d7ab1745c33e5650a", + "file": "benchmarks/data/.json", + "generated": "2026-11-07" + }, + "hosts": [ + { + "name": "Arrow Lake", + "source": { + "rind": "9e7f6a5a9ea59a0cf1251c24af6c5d4f21c2b0fd", + "cpu": "Intel(R) Core(TM) Ultra 7 270K Plus", + "jobs": 12, + "rustc": "rustc 1.98.1 (48a229cea 2026-09-01)", + "cc": "gcc (GCC) 16.2.0", + "date": "2026-11-07T14:06:19+00:00", + "runs": 3 + }, + "builds": [ + { + "name": "rind", + "seconds": 3.37, + "cpu_seconds": 7.98, + "bytes": 880496, + "tools": [], + "packages": 5 + }, + { + "name": "aws-lc-rs", + "seconds": 11.84, + "cpu_seconds": 37.09, + "bytes": 2991408, + "tools": ["cc"], + "packages": 14 + }, + { + "name": "ring", + "seconds": 4.95, + "cpu_seconds": 7.27, + "bytes": 744328, + "tools": ["cc"], + "packages": 9 + }, + { + "name": "rustcrypto", + "seconds": 2.81, + "cpu_seconds": 15.77, + "bytes": 540256, + "tools": [], + "packages": 57 + }, + { + "name": "graviola", + "seconds": 2.09, + "cpu_seconds": 4.45, + "bytes": 912944, + "tools": [], + "packages": 5 + }, + { + "name": "libcrux", + "seconds": 5.8, + "cpu_seconds": 13.41, + "bytes": 745648, + "tools": [], + "packages": 27 + }, + { + "name": "openssl", + "seconds": 3.35, + "cpu_seconds": 8.72, + "bytes": 377848, + "tools": ["cc", "pkg-config"], + "packages": 18 + }, + { + "name": "openssl-vendored", + "seconds": 24.66, + "cpu_seconds": 161.42, + "bytes": 5133408, + "tools": ["cc", "make", "perl"], + "packages": 19 + }, + { + "name": "rustls-rind", + "seconds": 4.21, + "cpu_seconds": 21.13, + "bytes": 2998240, + "tools": [], + "packages": 14 + }, + { + "name": "rustls-rind-lean", + "seconds": 4.5, + "cpu_seconds": 23.23, + "bytes": 1824096, + "tools": [], + "packages": 14 + }, + { + "name": "rustls-aws-lc-rs", + "seconds": 16.56, + "cpu_seconds": 55.22, + "bytes": 4114504, + "tools": ["cc"], + "packages": 20 + }, + { + "name": "rustls-ring", + "seconds": 7.78, + "cpu_seconds": 19.34, + "bytes": 1943808, + "tools": ["cc"], + "packages": 16 + } + ] + }, + { + "name": "Coffee Lake", + "source": { + "rind": "f95b91da886bee265dbd836192a7ade2f9158c47", + "cpu": "Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz", + "jobs": 3, + "rustc": "rustc 1.98.1 (48a229cea 2026-09-01)", + "cc": "gcc (GCC) 16.2.0", + "date": "2026-11-06T16:12:00+00:00", + "runs": 3 + }, + "builds": [ + { + "name": "rind", + "seconds": 7.25, + "cpu_seconds": 12.41, + "bytes": 878176, + "tools": [], + "packages": 5 + }, + { + "name": "aws-lc-rs", + "seconds": 26.18, + "cpu_seconds": 62.88, + "bytes": 2991408, + "tools": ["cc"], + "packages": 14 + }, + { + "name": "ring", + "seconds": 9.32, + "cpu_seconds": 12.08, + "bytes": 744328, + "tools": ["cc"], + "packages": 9 + }, + { + "name": "rustcrypto", + "seconds": 8.26, + "cpu_seconds": 24.02, + "bytes": 540320, + "tools": [], + "packages": 57 + }, + { + "name": "graviola", + "seconds": 3.83, + "cpu_seconds": 6.49, + "bytes": 912944, + "tools": [], + "packages": 5 + }, + { + "name": "libcrux", + "seconds": 9.68, + "cpu_seconds": 20.19, + "bytes": 745664, + "tools": [], + "packages": 27 + }, + { + "name": "openssl", + "seconds": 5.81, + "cpu_seconds": 11.62, + "bytes": 377864, + "tools": ["cc", "pkg-config"], + "packages": 18 + }, + { + "name": "openssl-vendored", + "seconds": 82.35, + "cpu_seconds": 220.19, + "bytes": 5133408, + "tools": ["cc", "make", "perl"], + "packages": 19 + }, + { + "name": "rustls-rind", + "seconds": 11.33, + "cpu_seconds": 31.48, + "bytes": 2953936, + "tools": [], + "packages": 14 + }, + { + "name": "rustls-rind-lean", + "seconds": 11.79, + "cpu_seconds": 32.75, + "bytes": 1821344, + "tools": [], + "packages": 14 + }, + { + "name": "rustls-aws-lc-rs", + "seconds": 36.62, + "cpu_seconds": 88.73, + "bytes": 4114504, + "tools": ["cc"], + "packages": 20 + }, + { + "name": "rustls-ring", + "seconds": 16.39, + "cpu_seconds": 30.53, + "bytes": 1943808, + "tools": ["cc"], + "packages": 16 + } + ] + }, + { + "name": "Apple M4", + "source": { + "rind": "9e7f6a5a9ea59a0cf1251c24af6c5d4f21c2b0fd", + "cpu": "Apple M4", + "jobs": 4, + "rustc": "rustc 1.98.1 (48a229cea 2026-09-01)", + "cc": "clang version 21.1.8", + "date": "2026-11-07T14:47:14+00:00", + "runs": 3 + }, + "builds": [ + { + "name": "rind", + "seconds": 4.01, + "cpu_seconds": 7.54, + "bytes": 674336, + "tools": [], + "packages": 5 + }, + { + "name": "aws-lc-rs", + "seconds": 29.03, + "cpu_seconds": 92.07, + "bytes": 2143280, + "tools": ["cc"], + "packages": 14 + }, + { + "name": "ring", + "seconds": 8.22, + "cpu_seconds": 10.21, + "bytes": 640592, + "tools": ["cc"], + "packages": 9 + }, + { + "name": "rustcrypto", + "seconds": 5.11, + "cpu_seconds": 16.02, + "bytes": 461696, + "tools": [], + "packages": 52 + }, + { + "name": "graviola", + "seconds": 3.06, + "cpu_seconds": 5.53, + "bytes": 821088, + "tools": [], + "packages": 5 + }, + { + "name": "libcrux", + "seconds": 8.04, + "cpu_seconds": 17.73, + "bytes": 589552, + "tools": [], + "packages": 27 + }, + { + "name": "openssl", + "seconds": 4.57, + "cpu_seconds": 10.2, + "bytes": 361648, + "tools": ["cc"], + "packages": 18 + }, + { + "name": "openssl-vendored", + "seconds": 131.72, + "cpu_seconds": 420.87, + "bytes": 3751488, + "tools": ["cc", "make", "perl"], + "packages": 19 + }, + { + "name": "rustls-rind", + "seconds": 6.52, + "cpu_seconds": 21.58, + "bytes": 2171632, + "tools": [], + "packages": 14 + }, + { + "name": "rustls-rind-lean", + "seconds": 6.7, + "cpu_seconds": 22.12, + "bytes": 1536256, + "tools": [], + "packages": 14 + }, + { + "name": "rustls-aws-lc-rs", + "seconds": 34.04, + "cpu_seconds": 109.04, + "bytes": 3077120, + "tools": ["cc"], + "packages": 20 + }, + { + "name": "rustls-ring", + "seconds": 12.18, + "cpu_seconds": 22.86, + "bytes": 1604896, + "tools": ["cc"], + "packages": 16 + } + ] + } + ] +} diff --git a/src/components/rind/data/libraries.json b/src/components/rind/data/libraries.json new file mode 100644 index 0000000..f285dd6 --- /dev/null +++ b/src/components/rind/data/libraries.json @@ -0,0 +1,3242 @@ +{ + "source": { + "rind": "00610affb74b8c64113c824d7ab1745c33e5650a", + "files": ["benchmarks/data/.json", "benchmarks/verified.toml", "admin/bench-report"], + "generated": "2026-11-07" + }, + "libraries": ["rind", "aws-lc-rs", "ring", "rustcrypto", "graviola", "libcrux", "openssl"], + "sections": [ + { + "name": "TLS 1.3 with rustls", + "operations": [ + { + "id": "rustls-full-handshake-group/x25519mlkem768", + "label": "full handshake, X25519MLKEM768" + }, + { + "id": "rustls-full-handshake-group/x25519", + "label": "full handshake, X25519" + }, + { + "id": "rustls-full-handshake-group/secp256r1", + "label": "full handshake, P-256" + }, + { + "id": "rustls-full-handshake-key/ed25519", + "label": "full handshake, Ed25519 certificate" + }, + { + "id": "rustls-full-handshake-key/rsa-2048", + "label": "full handshake, RSA-2048 certificate" + }, + { + "id": "rustls-resumed-handshake/x25519", + "label": "resumed handshake, X25519" + }, + { + "id": "rustls-bulk/aes128-gcm", + "label": "1 MB transfer, AES-128-GCM" + }, + { + "id": "rustls-bulk/aes256-gcm", + "label": "1 MB transfer, AES-256-GCM" + }, + { + "id": "rustls-bulk/chacha20poly1305", + "label": "1 MB transfer, ChaCha20-Poly1305" + } + ] + }, + { + "name": "AEADs", + "operations": [ + { + "id": "aes128-gcm/32B", + "label": "AES-128-GCM seal, 32 B" + }, + { + "id": "aes128-gcm/1350B", + "label": "AES-128-GCM seal, 1350 B" + }, + { + "id": "aes128-gcm/16KB", + "label": "AES-128-GCM seal, 16 KB" + }, + { + "id": "aes128-gcm-open/32B", + "label": "AES-128-GCM open, 32 B" + }, + { + "id": "aes128-gcm-open/1350B", + "label": "AES-128-GCM open, 1350 B" + }, + { + "id": "aes128-gcm-open/16KB", + "label": "AES-128-GCM open, 16 KB" + }, + { + "id": "aes256-gcm/32B", + "label": "AES-256-GCM seal, 32 B" + }, + { + "id": "aes256-gcm/1350B", + "label": "AES-256-GCM seal, 1350 B" + }, + { + "id": "aes256-gcm/16KB", + "label": "AES-256-GCM seal, 16 KB" + }, + { + "id": "aes256-gcm-open/32B", + "label": "AES-256-GCM open, 32 B" + }, + { + "id": "aes256-gcm-open/1350B", + "label": "AES-256-GCM open, 1350 B" + }, + { + "id": "aes256-gcm-open/16KB", + "label": "AES-256-GCM open, 16 KB" + }, + { + "id": "chacha20poly1305/32B", + "label": "ChaCha20-Poly1305 seal, 32 B" + }, + { + "id": "chacha20poly1305/1350B", + "label": "ChaCha20-Poly1305 seal, 1350 B" + }, + { + "id": "chacha20poly1305/16KB", + "label": "ChaCha20-Poly1305 seal, 16 KB" + }, + { + "id": "xchacha20poly1305/32B", + "label": "XChaCha20-Poly1305 seal, 32 B" + }, + { + "id": "xchacha20poly1305/1350B", + "label": "XChaCha20-Poly1305 seal, 1350 B" + }, + { + "id": "xchacha20poly1305/16KB", + "label": "XChaCha20-Poly1305 seal, 16 KB" + } + ] + }, + { + "name": "QUIC header protection", + "operations": [ + { + "id": "quic-header-protection/aes128", + "label": "AES-128 header protection" + }, + { + "id": "quic-header-protection/aes256", + "label": "AES-256 header protection" + }, + { + "id": "quic-header-protection/chacha20", + "label": "ChaCha20 header protection" + } + ] + }, + { + "name": "Key agreement", + "operations": [ + { + "id": "x25519-ecdh", + "label": "X25519" + }, + { + "id": "p256-ecdh", + "label": "P-256 ECDH" + } + ] + }, + { + "name": "Signatures", + "operations": [ + { + "id": "ed25519-sign", + "label": "Ed25519 sign" + }, + { + "id": "ed25519-verify", + "label": "Ed25519 verify" + }, + { + "id": "p256-ecdsa-sign", + "label": "P-256 ECDSA sign" + }, + { + "id": "p256-ecdsa-verify", + "label": "P-256 ECDSA verify" + } + ] + }, + { + "name": "Hashes and KDFs", + "operations": [ + { + "id": "sha256/64B", + "label": "SHA-256, 64 B" + }, + { + "id": "sha256/1350B", + "label": "SHA-256, 1350 B" + }, + { + "id": "sha256/16KB", + "label": "SHA-256, 16 KB" + }, + { + "id": "sha512/64B", + "label": "SHA-512, 64 B" + }, + { + "id": "sha512/1350B", + "label": "SHA-512, 1350 B" + }, + { + "id": "sha512/16KB", + "label": "SHA-512, 16 KB" + }, + { + "id": "hmac-sha256/64B", + "label": "HMAC-SHA256, 64 B" + }, + { + "id": "hmac-sha256/1350B", + "label": "HMAC-SHA256, 1350 B" + }, + { + "id": "hkdf-sha256/extract-expand", + "label": "HKDF-SHA256 extract and expand" + }, + { + "id": "hkdf-sha256/expand", + "label": "HKDF-SHA256 expand" + } + ] + }, + { + "name": "RSA", + "operations": [ + { + "id": "rsa2048-pkcs1-sha256-sign", + "label": "RSA-2048 PKCS#1 sign" + }, + { + "id": "rsa2048-pkcs1-sha256-verify", + "label": "RSA-2048 PKCS#1 verify" + }, + { + "id": "rsa2048-pss-sha256-sign", + "label": "RSA-2048 PSS sign" + }, + { + "id": "rsa2048-pss-sha256-verify", + "label": "RSA-2048 PSS verify" + } + ] + }, + { + "name": "ML-KEM", + "operations": [ + { + "id": "mlkem768-keygen", + "label": "ML-KEM-768 key generation" + }, + { + "id": "mlkem768-encaps", + "label": "ML-KEM-768 encapsulate" + }, + { + "id": "mlkem768-decaps", + "label": "ML-KEM-768 decapsulate" + } + ] + }, + { + "name": "P-384 and P-521", + "operations": [ + { + "id": "p384-ecdh", + "label": "P-384 ECDH" + }, + { + "id": "p384-ecdsa-sign", + "label": "P-384 ECDSA sign" + }, + { + "id": "p384-ecdsa-verify", + "label": "P-384 ECDSA verify" + }, + { + "id": "p521-ecdh", + "label": "P-521 ECDH" + }, + { + "id": "p521-ecdsa-sign", + "label": "P-521 ECDSA sign" + }, + { + "id": "p521-ecdsa-verify", + "label": "P-521 ECDSA verify" + } + ] + } + ], + "rows": [ + "AES-GCM", + "ChaCha20-Poly1305", + "XChaCha20-Poly1305", + "AES header protection", + "ChaCha20 header protection", + "SHA-256", + "SHA-512", + "HMAC-SHA256", + "HKDF-SHA256", + "X25519", + "Ed25519", + "P-256", + "P-384", + "P-521", + "RSA-2048 PSS", + "RSA-2048 PKCS#1", + "ML-KEM-768" + ], + "partial": { + "x86_64": { + "rind": { + "AES-GCM": { + "proof": "Vale's F* AES-GCM, for every message without VAES but only short ones with it", + "link": "https://github.com/moq-dev/rind/blob/main/ALGORITHMS.md" + }, + "Ed25519": { + "proof": "s2n-bignum's HOL Light scalar multiplications", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/x86/proofs" + }, + "P-256": { + "proof": "s2n-bignum's HOL Light scalar multiplication, for ECDH", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/x86/proofs" + }, + "P-384": { + "proof": "s2n-bignum's HOL Light scalar multiplication, for ECDH", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/x86/proofs" + }, + "P-521": { + "proof": "s2n-bignum's HOL Light scalar multiplication, for ECDH", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/x86/proofs" + }, + "ML-KEM-768": { + "proof": "s2n-bignum's and mlkem-native's HOL Light NTT and sampling", + "link": "https://github.com/pq-code-package/mlkem-native/tree/main/proofs/hol_light/x86_64/proofs" + } + }, + "aws-lc-rs": { + "AES-GCM": { + "proof": "aws-lc-verification's SAW AES-GCM, for AES-256 only", + "link": "https://github.com/awslabs/aws-lc-verification/blob/797302470c1703cbb1a3a6fa98daffef0bfd3d80/README.md" + }, + "AES header protection": { + "proof": "aws-lc-verification's SAW AES block, for AES-256 only", + "link": "https://github.com/awslabs/aws-lc-verification/blob/797302470c1703cbb1a3a6fa98daffef0bfd3d80/README.md" + }, + "X25519": { + "proof": "s2n-bignum's HOL Light X25519 ladder", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/x86/proofs" + }, + "Ed25519": { + "proof": "s2n-bignum's HOL Light scalar multiplications", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/x86/proofs" + }, + "P-256": { + "proof": "s2n-bignum's HOL Light scalar multiplication, for ECDH", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/x86/proofs" + }, + "P-384": { + "proof": "s2n-bignum's HOL Light scalar multiplication, for ECDH", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/x86/proofs" + }, + "P-521": { + "proof": "s2n-bignum's HOL Light scalar multiplication, for ECDH", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/x86/proofs" + }, + "ML-KEM-768": { + "proof": "mlkem-native's HOL Light AVX2 NTT and sampling", + "link": "https://github.com/pq-code-package/mlkem-native/tree/main/proofs/hol_light/x86_64/proofs" + } + }, + "graviola": { + "X25519": { + "proof": "s2n-bignum's HOL Light X25519 ladder", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/x86/proofs" + }, + "Ed25519": { + "proof": "s2n-bignum's HOL Light scalar multiplications", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/x86/proofs" + }, + "ML-KEM-768": { + "proof": "s2n-bignum's HOL Light NTT and base multiplication", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/x86/proofs" + } + }, + "libcrux": { + "XChaCha20-Poly1305": { + "proof": "HACL*'s F* ChaCha20-Poly1305, under an unverified HChaCha20", + "link": "https://github.com/hacl-star/hacl-star/tree/main/code/chacha20poly1305" + } + } + }, + "aarch64": { + "rind": { + "Ed25519": { + "proof": "s2n-bignum's HOL Light scalar multiplications", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/arm/proofs" + }, + "P-384": { + "proof": "s2n-bignum's HOL Light scalar multiplication, for ECDH", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/arm/proofs" + }, + "P-521": { + "proof": "s2n-bignum's HOL Light scalar multiplication, for ECDH", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/arm/proofs" + }, + "ML-KEM-768": { + "proof": "s2n-bignum's HOL Light NTT and sampling", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/arm/proofs" + } + }, + "aws-lc-rs": { + "X25519": { + "proof": "s2n-bignum's HOL Light X25519 ladder", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/arm/proofs" + }, + "Ed25519": { + "proof": "s2n-bignum's HOL Light scalar multiplications", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/arm/proofs" + }, + "P-256": { + "proof": "s2n-bignum's HOL Light scalar multiplication, for ECDH", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/arm/proofs" + }, + "P-384": { + "proof": "s2n-bignum's HOL Light scalar multiplication, for ECDH", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/arm/proofs" + }, + "P-521": { + "proof": "s2n-bignum's HOL Light scalar multiplication, for ECDH", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/arm/proofs" + }, + "ML-KEM-768": { + "proof": "mlkem-native's HOL Light aarch64 NTT and sampling", + "link": "https://github.com/pq-code-package/mlkem-native/tree/main/proofs/hol_light/aarch64/proofs" + } + }, + "graviola": { + "X25519": { + "proof": "s2n-bignum's HOL Light X25519 ladder", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/arm/proofs" + }, + "Ed25519": { + "proof": "s2n-bignum's HOL Light scalar multiplications", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/arm/proofs" + }, + "ML-KEM-768": { + "proof": "s2n-bignum's HOL Light NTT and base multiplication", + "link": "https://github.com/awslabs/s2n-bignum/tree/main/arm/proofs" + } + }, + "libcrux": { + "XChaCha20-Poly1305": { + "proof": "HACL*'s F* ChaCha20-Poly1305, under an unverified HChaCha20", + "link": "https://github.com/hacl-star/hacl-star/tree/main/code/chacha20poly1305" + } + } + } + }, + "hosts": [ + { + "name": "Arrow Lake", + "arch": "x86_64", + "source": { + "rind": "9e7f6a5a9ea59a0cf1251c24af6c5d4f21c2b0fd", + "cpu": "Intel(R) Core(TM) Ultra 7 270K Plus", + "date": "2026-11-07T13:37:17+00:00", + "versions": { + "rind": { + "rind": "0.2.1", + "rind-rustls": "0.23.0" + }, + "aws-lc-rs": { + "aws-lc-rs": "1.19.0", + "aws-lc-sys": "0.47.0" + }, + "ring": { + "ring": "0.17.14" + }, + "rustcrypto": { + "aes-gcm": "0.11.1", + "chacha20poly1305": "0.11.0", + "sha2": "0.11.1", + "sha3": "0.12.0", + "hmac": "0.13.0", + "hkdf": "0.13.0", + "p256": "0.14.0", + "p384": "0.14.0", + "p521": "0.14.0", + "rsa": "0.10.0-rc.19", + "ml-kem": "0.3.4", + "ed25519-dalek": "3.0.0", + "x25519-dalek": "3.0.0" + }, + "graviola": { + "graviola": "0.4.4", + "rustls-graviola": "0.4.0" + }, + "libcrux": { + "libcrux-aes": "0.0.10", + "libcrux-chacha20poly1305": "0.0.10", + "libcrux-ecdh": "0.0.9", + "libcrux-ecdsa": "0.0.9", + "libcrux-ed25519": "0.0.10", + "libcrux-hkdf": "0.0.9", + "libcrux-hmac": "0.0.9", + "libcrux-ml-kem": "0.0.11", + "libcrux-rsa": "0.0.9", + "libcrux-sha2": "0.0.9", + "libcrux-sha3": "0.0.11" + }, + "openssl": { + "openssl": "0.10.82", + "openssl-sys": "0.9.118", + "rustls-openssl": "0.4.2", + "linked": "OpenSSL 3.5.9 29 Sep 2026 (Library: OpenSSL 3.5.9 29 Sep 2026)" + }, + "tls": { + "rustls": "0.23.46" + } + } + }, + "times": { + "rustls-full-handshake-group/x25519mlkem768": { + "rind": 172303.64461947687, + "aws-lc-rs": 233731.1471129501, + "graviola": 188190.19006132704, + "openssl": 438878.9896601153 + }, + "rustls-full-handshake-group/x25519": { + "rind": 151321.32192625978, + "aws-lc-rs": 201934.30900743805, + "ring": 221013.4437594207, + "graviola": 161402.26108763114, + "openssl": 366379.91121915175 + }, + "rustls-full-handshake-group/secp256r1": { + "rind": 174551.25904388947, + "aws-lc-rs": 227862.49803950544, + "ring": 219505.20030638884, + "graviola": 191811.12497266143, + "openssl": 400763.1065449978 + }, + "rustls-full-handshake-key/ed25519": { + "rind": 121900.17352800355, + "aws-lc-rs": 166630.28164917984, + "ring": 202036.64412196443, + "graviola": 123710.98283552534, + "openssl": 368209.43157233635 + }, + "rustls-full-handshake-key/rsa-2048": { + "rind": 432829.6602512192, + "aws-lc-rs": 480430.2605260825, + "ring": 488218.6892699867, + "graviola": 440421.7762849121, + "openssl": 670543.5991813211 + }, + "rustls-resumed-handshake/x25519": { + "rind": 54393.840452194476, + "aws-lc-rs": 101361.50935865229, + "ring": 111286.86569233042, + "graviola": 55618.2704378199, + "openssl": 232436.5798758682 + }, + "rustls-bulk/aes128-gcm": { + "rind": 168209.4705319935, + "aws-lc-rs": 233340.55045662777, + "ring": 170075.07825328803, + "graviola": 289614.6726417418, + "openssl": 250850.85143293435 + }, + "rustls-bulk/aes256-gcm": { + "rind": 184540.8985577065, + "aws-lc-rs": 265287.4674242648, + "ring": 188671.20969410375, + "graviola": 337961.7777907492, + "openssl": 285785.9151844737 + }, + "rustls-bulk/chacha20poly1305": { + "rind": 596912.0600916211, + "aws-lc-rs": 595414.4498448352, + "ring": 590487.3292093986, + "graviola": 1160609.3795238093, + "openssl": 658480.2192670312 + }, + "aes128-gcm/32B": { + "rind": 19.746949580422342, + "aws-lc-rs": 37.53366868712758, + "ring": 41.07747092267411, + "rustcrypto": 73.14946279006158, + "graviola": 42.14599664492454, + "libcrux": 170.64893360294954, + "openssl": 56.84287538709346 + }, + "aes128-gcm/1350B": { + "rind": 92.65762186486914, + "aws-lc-rs": 158.6357668453869, + "ring": 119.49365006059759, + "rustcrypto": 278.3612755111838, + "graviola": 225.69116689643127, + "libcrux": 1979.9750792859818, + "openssl": 160.0054391621612 + }, + "aes128-gcm/16KB": { + "rind": 799.0393576206395, + "aws-lc-rs": 1322.8225328669594, + "ring": 817.8716201390074, + "rustcrypto": 2488.0224065347893, + "graviola": 2054.634860932619, + "libcrux": 22046.322340333536, + "openssl": 1345.0454593726408 + }, + "aes128-gcm-open/32B": { + "rind": 15.141390013867618, + "aws-lc-rs": 37.81932226175298, + "ring": 41.09339760364453, + "rustcrypto": 78.00973588687573, + "graviola": 36.27044102098532, + "libcrux": 161.59763873928435, + "openssl": 58.9664843592685 + }, + "aes128-gcm-open/1350B": { + "rind": 89.45517059259937, + "aws-lc-rs": 150.8167040522719, + "ring": 113.60432726291496, + "rustcrypto": 283.1588719945938, + "graviola": 174.78753147011918, + "libcrux": 1993.7134171626117, + "openssl": 161.67150940709666 + }, + "aes128-gcm-open/16KB": { + "rind": 792.6638107758239, + "aws-lc-rs": 1263.4791311844165, + "ring": 814.2382096527748, + "rustcrypto": 2505.4509875487834, + "graviola": 1398.9231256629973, + "libcrux": 21935.383362286477, + "openssl": 1286.7861153335605 + }, + "aes256-gcm/32B": { + "rind": 21.359315212272744, + "aws-lc-rs": 39.17103225543588, + "ring": 43.17524180628785, + "rustcrypto": 78.22023256652304, + "graviola": 44.52852253232011, + "libcrux": 217.07683353305674, + "openssl": 61.24312243208717 + }, + "aes256-gcm/1350B": { + "rind": 107.22592864239105, + "aws-lc-rs": 174.987533132129, + "ring": 133.53413554806923, + "rustcrypto": 312.7041962871171, + "graviola": 257.31636369740664, + "libcrux": 2873.809701833559, + "openssl": 184.0609176892426 + }, + "aes256-gcm/16KB": { + "rind": 953.6949999304722, + "aws-lc-rs": 1580.2553137848327, + "ring": 974.6140575405718, + "rustcrypto": 2902.3261399114067, + "graviola": 2457.8666247601695, + "libcrux": 32858.19057671518, + "openssl": 1601.9930557594687 + }, + "aes256-gcm-open/32B": { + "rind": 16.36006000273459, + "aws-lc-rs": 37.760775546967544, + "ring": 43.00458440518072, + "rustcrypto": 82.27389385816223, + "graviola": 37.742579057354384, + "libcrux": 214.64644106485576, + "openssl": 61.08817197648884 + }, + "aes256-gcm-open/1350B": { + "rind": 98.86964073378171, + "aws-lc-rs": 171.9224988446178, + "ring": 121.22066060903276, + "rustcrypto": 317.69921186778976, + "graviola": 200.9636378776052, + "libcrux": 2849.2671763264307, + "openssl": 188.69435557663402 + }, + "aes256-gcm-open/16KB": { + "rind": 899.0658232898955, + "aws-lc-rs": 1551.3657814204319, + "ring": 932.8564284011692, + "rustcrypto": 2920.919122094826, + "graviola": 1714.1936696010348, + "libcrux": 32612.813677366164, + "openssl": 1578.9833448953984 + }, + "chacha20poly1305/32B": { + "rind": 98.45560185901977, + "aws-lc-rs": 103.17589039388896, + "ring": 98.87613582529383, + "rustcrypto": 1051.3328198924767, + "graviola": 177.4796770221076, + "libcrux": 156.8485187765772, + "openssl": 174.9169810680925 + }, + "chacha20poly1305/1350B": { + "rind": 440.27024447133556, + "aws-lc-rs": 446.29926025543625, + "ring": 448.024827836542, + "rustcrypto": 1644.0746638625872, + "graviola": 889.8492564117242, + "libcrux": 1769.6891731230692, + "openssl": 586.5285385043761 + }, + "chacha20poly1305/16KB": { + "rind": 4186.192835508693, + "aws-lc-rs": 4129.047837175509, + "ring": 4119.637287668859, + "rustcrypto": 8031.7869985517955, + "graviola": 8290.059216746302, + "libcrux": 19308.11023563117, + "openssl": 4345.291100413234 + }, + "xchacha20poly1305/32B": { + "rind": 185.85064466169132, + "aws-lc-rs": 198.93098609933983, + "rustcrypto": 1154.3210407503002, + "graviola": 254.52110751316087, + "libcrux": 244.35012286759152 + }, + "xchacha20poly1305/1350B": { + "rind": 528.6618851485149, + "aws-lc-rs": 539.2512707043926, + "rustcrypto": 1729.7892493880147, + "graviola": 973.6021023966356, + "libcrux": 1834.7060447192825 + }, + "xchacha20poly1305/16KB": { + "rind": 4174.40743916642, + "aws-lc-rs": 4234.980958056076, + "rustcrypto": 8153.435007648405, + "graviola": 8395.075005047278, + "libcrux": 19609.596587995824 + }, + "quic-header-protection/aes128": { + "rind": 1.7057217073437445, + "aws-lc-rs": 3.251223987832192, + "ring": 3.457281430100614 + }, + "quic-header-protection/aes256": { + "rind": 2.0766344986236245, + "aws-lc-rs": 5.3155687315201225, + "ring": 5.132923075251203 + }, + "quic-header-protection/chacha20": { + "rind": 53.09920597377861, + "aws-lc-rs": 68.47819606831247, + "ring": 60.39017214914317 + }, + "x25519-ecdh": { + "rind": 18203.08785397943, + "aws-lc-rs": 19244.324777454152, + "ring": 35628.691866236666, + "rustcrypto": 36059.78595485009, + "graviola": 18091.50587243799, + "libcrux": 42676.12114575637, + "openssl": 33951.030497676635 + }, + "p256-ecdh": { + "rind": 29523.557551703998, + "aws-lc-rs": 31767.263718043447, + "ring": 33635.4506456168, + "rustcrypto": 121298.242327176, + "graviola": 33672.66087893864, + "libcrux": 171676.0393837742, + "openssl": 52916.597788778876 + }, + "ed25519-sign": { + "rind": 4111.479154925271, + "aws-lc-rs": 4485.754918745606, + "ring": 13114.176522831387, + "rustcrypto": 9600.99246111029, + "graviola": 4398.692000799729, + "libcrux": 28537.099566242337, + "openssl": 13672.03782756186 + }, + "ed25519-verify": { + "rind": 21428.515593742744, + "aws-lc-rs": 21414.2071281851, + "ring": 25925.14302915042, + "rustcrypto": 21874.072632417825, + "graviola": 21450.223807553462, + "libcrux": 41826.85573104773, + "openssl": 44788.53066435855 + }, + "p256-ecdsa-sign": { + "rind": 6738.318760831307, + "aws-lc-rs": 12249.17650199196, + "ring": 12200.802390894587, + "rustcrypto": 31315.209107044248, + "graviola": 8968.389966761435, + "libcrux": 61813.46097088813, + "openssl": 14452.256443173103 + }, + "p256-ecdsa-verify": { + "rind": 30587.991460174377, + "aws-lc-rs": 29751.07217792227, + "ring": 33231.94069651741, + "rustcrypto": 103239.12943254027, + "graviola": 32359.01470588693, + "libcrux": 147266.68459760604, + "openssl": 46462.86099601005 + }, + "sha256/64B": { + "rind": 28.172676969162893, + "aws-lc-rs": 57.01276505236001, + "ring": 56.31874103195594, + "rustcrypto": 39.104576234058996, + "graviola": 40.08559266443109, + "libcrux": 217.50730438169248, + "openssl": 158.28726392259222 + }, + "sha256/1350B": { + "rind": 268.92496881098225, + "aws-lc-rs": 306.11777763239104, + "ring": 304.3367208034221, + "rustcrypto": 295.6638055198604, + "graviola": 292.23294489717057, + "libcrux": 2286.170527789329, + "openssl": 406.15979595595184 + }, + "sha256/16KB": { + "rind": 3189.9143829800014, + "aws-lc-rs": 3231.5506677064527, + "ring": 3223.1275321173102, + "rustcrypto": 3220.2731376033935, + "graviola": 3216.47218129316, + "libcrux": 26897.549368225595, + "openssl": 3355.415052047688 + }, + "sha512/64B": { + "rind": 60.090929140141704, + "aws-lc-rs": 133.8019829204203, + "ring": 139.97080335000595, + "rustcrypto": 120.18388287790492, + "graviola": 148.4575746586375, + "libcrux": 166.17978856992008, + "openssl": 225.8325588132335 + }, + "sha512/1350B": { + "rind": 249.33934868874138, + "aws-lc-rs": 1243.4708805469318, + "ring": 1258.5604929011652, + "rustcrypto": 1168.0090951281636, + "graviola": 1486.2947918247253, + "libcrux": 1718.1407062259996, + "openssl": 1171.3578442313012 + }, + "sha512/16KB": { + "rind": 2625.8782779607436, + "aws-lc-rs": 14115.311413185053, + "ring": 14096.542254030332, + "rustcrypto": 13511.495519499711, + "graviola": 17497.58025191457, + "libcrux": 20102.91892271317, + "openssl": 12288.512652518373 + }, + "hmac-sha256/64B": { + "rind": 75.08938428017244, + "aws-lc-rs": 179.9443864665826, + "ring": 145.19689182382092, + "rustcrypto": 103.0704074524284, + "graviola": 110.00800428550318, + "libcrux": 536.9835110429013, + "openssl": 1554.7293078951257 + }, + "hmac-sha256/1350B": { + "rind": 328.1901390001888, + "aws-lc-rs": 434.915899860939, + "ring": 397.25244307629634, + "rustcrypto": 355.56820828978954, + "graviola": 357.83183002336574, + "libcrux": 2676.179290993419, + "openssl": 1809.5311845415522 + }, + "hkdf-sha256/extract-expand": { + "rind": 157.76140792685047, + "aws-lc-rs": 284.6538582620157, + "ring": 302.5501807490982, + "rustcrypto": 222.5832828418161, + "libcrux": 965.4921747377815, + "openssl": 1723.0448556606789 + }, + "hkdf-sha256/expand": { + "rind": 66.1334910677645, + "aws-lc-rs": 124.11689168829068, + "ring": 120.39983565531816, + "rustcrypto": 83.8216579873762, + "libcrux": 480.4296643744097, + "openssl": 1233.1469665631623 + }, + "rsa2048-pkcs1-sha256-sign": { + "rind": 341491.1479976356, + "aws-lc-rs": 344239.68309442885, + "ring": 336103.55799911334, + "rustcrypto": 580178.2960351707, + "graviola": 343747.91087631154, + "openssl": 393451.76934091916 + }, + "rsa2048-pkcs1-sha256-verify": { + "rind": 8920.560531187448, + "aws-lc-rs": 10955.983230812633, + "ring": 12783.959092848285, + "rustcrypto": 29013.88050271978, + "graviola": 13975.01862307161, + "openssl": 15510.445546449018 + }, + "rsa2048-pss-sha256-sign": { + "rind": 341450.67879858136, + "aws-lc-rs": 346554.3083242205, + "ring": 342489.2410669425, + "rustcrypto": 581164.5041066943, + "graviola": 344576.23691443773, + "libcrux": 3685243.782222224, + "openssl": 390435.895467711 + }, + "rsa2048-pss-sha256-verify": { + "rind": 9148.607974528797, + "aws-lc-rs": 11157.30143244175, + "ring": 13192.980341298244, + "rustcrypto": 35269.28881440207, + "graviola": 14304.829849901835, + "libcrux": 251906.13099157676, + "openssl": 16246.727593847727 + }, + "mlkem768-keygen": { + "rind": 6347.784516631085, + "aws-lc-rs": 8134.450316908607, + "rustcrypto": 39631.83017419092, + "graviola": 7373.593997741399, + "libcrux": 15015.03885953894, + "openssl": 19808.30902310231 + }, + "mlkem768-encaps": { + "rind": 6501.104132169544, + "aws-lc-rs": 8479.00111768587, + "rustcrypto": 41379.01761075809, + "graviola": 8999.01048040625, + "libcrux": 12802.52163521973, + "openssl": 18773.77713554751 + }, + "mlkem768-decaps": { + "rind": 4644.475538517406, + "aws-lc-rs": 8897.287862942132, + "rustcrypto": 54867.5242572914, + "graviola": 6536.591512316559, + "libcrux": 13436.761811207987, + "openssl": 15774.655110481983 + }, + "p384-ecdh": { + "rind": 100196.45363184079, + "aws-lc-rs": 109335.57772326487, + "ring": 369833.1951588592, + "rustcrypto": 402094.8987734594, + "graviola": 174122.07773163883, + "openssl": 265210.4507846904 + }, + "p384-ecdsa-sign": { + "rind": 23479.4017040843, + "aws-lc-rs": 46549.82471905514, + "ring": 197307.8084340673, + "rustcrypto": 85504.70672760667, + "graviola": 90285.52533386814, + "openssl": 88979.82968777049 + }, + "p384-ecdsa-verify": { + "rind": 100098.30340131027, + "aws-lc-rs": 115713.21065464756, + "ring": 357263.16896704596, + "rustcrypto": 359612.70368257724, + "graviola": 166485.45916802128, + "openssl": 216274.25298359687 + }, + "p521-ecdh": { + "rind": 159566.10430545293, + "aws-lc-rs": 171503.9195825329, + "rustcrypto": 428265.5645603665, + "openssl": 276636.70270528545 + }, + "p521-ecdsa-sign": { + "rind": 40088.58121196, + "aws-lc-rs": 88283.11231987165, + "rustcrypto": 94088.23866832738, + "openssl": 127934.59818176445 + }, + "p521-ecdsa-verify": { + "rind": 145100.1962293483, + "aws-lc-rs": 186691.45868774937, + "rustcrypto": 352950.0369661593, + "openssl": 261102.6577331166 + } + }, + "coverage": { + "AES-GCM": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "none", + "openssl": "none" + }, + "ChaCha20-Poly1305": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "XChaCha20-Poly1305": { + "rind": "none", + "aws-lc-rs": "none", + "ring": null, + "rustcrypto": "none", + "graviola": "none", + "libcrux": "routine", + "openssl": null + }, + "AES header protection": { + "rind": "none", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": null, + "graviola": null, + "libcrux": null, + "openssl": null + }, + "ChaCha20 header protection": { + "rind": "e2e", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": null, + "graviola": null, + "libcrux": null, + "openssl": null + }, + "SHA-256": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "SHA-512": { + "rind": "none", + "aws-lc-rs": "e2e", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "HMAC-SHA256": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "HKDF-SHA256": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": null, + "libcrux": "e2e", + "openssl": "none" + }, + "X25519": { + "rind": "e2e", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "routine", + "libcrux": "e2e", + "openssl": "none" + }, + "Ed25519": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "routine", + "libcrux": "e2e", + "openssl": "none" + }, + "P-256": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "P-384": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": null, + "openssl": "none" + }, + "P-521": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": null, + "rustcrypto": "none", + "graviola": null, + "libcrux": null, + "openssl": "none" + }, + "RSA-2048 PSS": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "RSA-2048 PKCS#1": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": null, + "openssl": "none" + }, + "ML-KEM-768": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": null, + "rustcrypto": "none", + "graviola": "routine", + "libcrux": "none", + "openssl": "none" + } + } + }, + { + "name": "Zen 3", + "arch": "x86_64", + "source": { + "rind": "f95b91da886bee265dbd836192a7ade2f9158c47", + "cpu": "AMD Ryzen 9 5900XT 16-Core Processor", + "date": "2026-11-06T16:32:11+00:00", + "versions": { + "rind": { + "rind": "0.1.13", + "rind-rustls": "0.1.13" + }, + "aws-lc-rs": { + "aws-lc-rs": "1.19.0", + "aws-lc-sys": "0.47.0" + }, + "ring": { + "ring": "0.17.14" + }, + "rustcrypto": { + "aes-gcm": "0.11.1", + "chacha20poly1305": "0.11.0", + "sha2": "0.11.1", + "sha3": "0.12.0", + "hmac": "0.13.0", + "hkdf": "0.13.0", + "p256": "0.14.0", + "p384": "0.14.0", + "p521": "0.14.0", + "rsa": "0.10.0-rc.19", + "ml-kem": "0.3.4", + "ed25519-dalek": "3.0.0", + "x25519-dalek": "3.0.0" + }, + "graviola": { + "graviola": "0.4.3", + "rustls-graviola": "0.4.0" + }, + "libcrux": { + "libcrux-aes": "0.0.10", + "libcrux-chacha20poly1305": "0.0.10", + "libcrux-ecdh": "0.0.9", + "libcrux-ecdsa": "0.0.9", + "libcrux-ed25519": "0.0.10", + "libcrux-hkdf": "0.0.9", + "libcrux-hmac": "0.0.9", + "libcrux-ml-kem": "0.0.11", + "libcrux-rsa": "0.0.9", + "libcrux-sha2": "0.0.9", + "libcrux-sha3": "0.0.11" + }, + "openssl": { + "openssl": "0.10.82", + "openssl-sys": "0.9.118", + "rustls-openssl": "0.4.2", + "linked": "OpenSSL 3.5.9 29 Sep 2026 (Library: OpenSSL 3.5.9 29 Sep 2026)" + }, + "tls": { + "rustls": "0.23.46" + } + } + }, + "times": { + "rustls-full-handshake-group/x25519mlkem768": { + "rind": 260780.4484074676, + "aws-lc-rs": 331871.505627309, + "graviola": 342679.04537214915, + "openssl": 802570.3694517511 + }, + "rustls-full-handshake-group/x25519": { + "rind": 227823.68336732182, + "aws-lc-rs": 292134.0748160189, + "ring": 328461.79629673413, + "graviola": 238698.70035663267, + "openssl": 574279.8404566278 + }, + "rustls-full-handshake-group/secp256r1": { + "rind": 242758.89868085316, + "aws-lc-rs": 304367.3057056303, + "ring": 281925.87700113293, + "graviola": 270050.4174474164, + "openssl": 624351.3549194621 + }, + "rustls-full-handshake-key/ed25519": { + "rind": 186733.9460713758, + "aws-lc-rs": 233429.86192010247, + "ring": 292961.966264716, + "graviola": 186046.53406605587, + "openssl": 640403.1801684647 + }, + "rustls-full-handshake-key/rsa-2048": { + "rind": 550143.3175838628, + "aws-lc-rs": 646281.1263070785, + "ring": 647360.2574582533, + "graviola": 567912.8249209399, + "openssl": 992047.1807063691 + }, + "rustls-resumed-handshake/x25519": { + "rind": 77192.5918856214, + "aws-lc-rs": 132666.7800177331, + "ring": 158106.22338850304, + "graviola": 77326.99750332496, + "openssl": 370514.08009309886 + }, + "rustls-bulk/aes128-gcm": { + "rind": 289425.64379488694, + "aws-lc-rs": 458206.86149992613, + "ring": 282217.04155066254, + "graviola": 424376.3461341806, + "openssl": 469836.607914881 + }, + "rustls-bulk/aes256-gcm": { + "rind": 292743.5694359884, + "aws-lc-rs": 461275.7782636323, + "ring": 289903.7481296488, + "graviola": 490288.78706812474, + "openssl": 533200.6291133441 + }, + "rustls-bulk/chacha20poly1305": { + "rind": 688782.5718161667, + "aws-lc-rs": 687525.271556081, + "ring": 693007.3277316388, + "graviola": 1372989.95, + "openssl": 782981.7795241614 + }, + "aes128-gcm/32B": { + "rind": 38.71781004146106, + "aws-lc-rs": 78.18123602992911, + "ring": 56.29595468671775, + "rustcrypto": 96.96354522191186, + "graviola": 69.64893975805013, + "libcrux": 321.1510688259032, + "openssl": 115.16628382591279 + }, + "aes128-gcm/1350B": { + "rind": 164.7907743033959, + "aws-lc-rs": 291.45977784805507, + "ring": 191.30515759333656, + "rustcrypto": 433.59781089432875, + "graviola": 294.544534988775, + "libcrux": 4718.6859278643815, + "openssl": 326.496180077384 + }, + "aes128-gcm/16KB": { + "rind": 1378.160155639028, + "aws-lc-rs": 2631.490105430963, + "ring": 1390.5736936742217, + "rustcrypto": 4279.150361625876, + "graviola": 2568.4700093207616, + "libcrux": 53903.71160558593, + "openssl": 2606.678917002174 + }, + "aes128-gcm-open/32B": { + "rind": 44.381446002824276, + "aws-lc-rs": 72.39146350246212, + "ring": 57.88729926164423, + "rustcrypto": 101.77797133462741, + "graviola": 64.57911474235208, + "libcrux": 317.4279780523032, + "openssl": 117.72176747379157 + }, + "aes128-gcm-open/1350B": { + "rind": 174.3700001910275, + "aws-lc-rs": 298.2697346469915, + "ring": 184.7831183861872, + "rustcrypto": 450.60785256378966, + "graviola": 304.66672416137135, + "libcrux": 3915.9811960714924, + "openssl": 332.94154273480865 + }, + "aes128-gcm-open/16KB": { + "rind": 1438.5637060330264, + "aws-lc-rs": 2721.8399650039632, + "ring": 1450.6497199735666, + "rustcrypto": 4287.566708001105, + "graviola": 2653.369770485444, + "libcrux": 44290.48332242606, + "openssl": 2771.743101320518 + }, + "aes256-gcm/32B": { + "rind": 41.12624580804068, + "aws-lc-rs": 81.67287715485598, + "ring": 56.923970565102294, + "rustcrypto": 100.79500719003778, + "graviola": 74.40760387950502, + "libcrux": 425.5936084666091, + "openssl": 118.0071271386442 + }, + "aes256-gcm/1350B": { + "rind": 184.3356665663656, + "aws-lc-rs": 311.3959418305522, + "ring": 205.0115597532675, + "rustcrypto": 488.6783901794388, + "graviola": 337.4235382065502, + "libcrux": 6912.772572298535, + "openssl": 345.3119771050344 + }, + "aes256-gcm/16KB": { + "rind": 1509.9385955251023, + "aws-lc-rs": 2779.682549439349, + "ring": 1530.7028236636559, + "rustcrypto": 4778.539619572212, + "graviola": 2976.366100147776, + "libcrux": 80608.28103221516, + "openssl": 2822.3494130380036 + }, + "aes256-gcm-open/32B": { + "rind": 48.437449813823704, + "aws-lc-rs": 78.56685596903668, + "ring": 60.78052182940942, + "rustcrypto": 108.5477081028688, + "graviola": 67.51808037014749, + "libcrux": 440.7380738169481, + "openssl": 121.93546746055961 + }, + "aes256-gcm-open/1350B": { + "rind": 191.64544793862083, + "aws-lc-rs": 321.7740518643795, + "ring": 203.87999068803387, + "rustcrypto": 507.53927385472986, + "graviola": 341.43634471476116, + "libcrux": 6787.904072571437, + "openssl": 353.76517782827835 + }, + "aes256-gcm-open/16KB": { + "rind": 1603.7028921355225, + "aws-lc-rs": 2919.0870604764154, + "ring": 1617.658888692568, + "rustcrypto": 4931.822075141028, + "graviola": 3044.9247502887665, + "libcrux": 79185.40512782622, + "openssl": 2975.6487480581427 + }, + "chacha20poly1305/32B": { + "rind": 113.65893860745757, + "aws-lc-rs": 119.12073258814414, + "ring": 112.54149771549098, + "rustcrypto": 1179.3188531404753, + "graviola": 215.6158614269785, + "libcrux": 220.29172298209983, + "openssl": 257.3650611662894 + }, + "chacha20poly1305/1350B": { + "rind": 532.902464971817, + "aws-lc-rs": 532.2288036733263, + "ring": 527.4927198882623, + "rustcrypto": 1927.9016946257525, + "graviola": 1081.162616956621, + "libcrux": 2335.031270756997, + "openssl": 745.3420585861181 + }, + "chacha20poly1305/16KB": { + "rind": 4675.981236361267, + "aws-lc-rs": 4784.972222467859, + "ring": 4678.818568932908, + "rustcrypto": 10088.715890054676, + "graviola": 10145.577916258613, + "libcrux": 26699.099586741282, + "openssl": 5142.800268695267 + }, + "xchacha20poly1305/32B": { + "rind": 243.04294919955078, + "aws-lc-rs": 266.74500117823146, + "rustcrypto": 1361.3235103721327, + "graviola": 357.4893359909269, + "libcrux": 351.3154649264112 + }, + "xchacha20poly1305/1350B": { + "rind": 774.9947455618866, + "aws-lc-rs": 722.9400653166238, + "rustcrypto": 2179.5863545724756, + "graviola": 1310.95600824662, + "libcrux": 2699.132015854057 + }, + "xchacha20poly1305/16KB": { + "rind": 5232.509970444806, + "aws-lc-rs": 5374.135824035762, + "rustcrypto": 11379.844303686046, + "graviola": 10803.818398269677, + "libcrux": 28662.65571323017 + }, + "quic-header-protection/aes128": { + "rind": 3.9854584142848997, + "aws-lc-rs": 5.786550145537476, + "ring": 6.943754895172456 + }, + "quic-header-protection/aes256": { + "rind": 5.852553637296669, + "aws-lc-rs": 7.705988365785333, + "ring": 9.58496873322171 + }, + "quic-header-protection/chacha20": { + "rind": 60.882555909094684, + "aws-lc-rs": 81.56651536425535, + "ring": 74.1403129677756 + }, + "x25519-ecdh": { + "rind": 23974.12950589626, + "aws-lc-rs": 24608.351602630413, + "ring": 46724.662013163426, + "rustcrypto": 52089.19438870007, + "graviola": 23944.31350317718, + "libcrux": 64595.76350879267, + "openssl": 49702.71299788188 + }, + "p256-ecdh": { + "rind": 42818.72608583673, + "aws-lc-rs": 42597.45412221073, + "ring": 46046.87106932967, + "rustcrypto": 268619.79256489826, + "graviola": 47865.2822673381, + "libcrux": 268702.67360918183, + "openssl": 71251.71736774051 + }, + "ed25519-sign": { + "rind": 5716.140016097538, + "aws-lc-rs": 6130.472676494272, + "ring": 17232.684260507926, + "rustcrypto": 13297.38926696401, + "graviola": 5827.021430355503, + "libcrux": 41369.354314959855, + "openssl": 23382.890414454763 + }, + "ed25519-verify": { + "rind": 27149.61003347447, + "aws-lc-rs": 27028.973508738934, + "ring": 34762.58573879776, + "rustcrypto": 24826.13810232008, + "graviola": 27077.867441460563, + "libcrux": 54515.02347889267, + "openssl": 79252.95914548544 + }, + "p256-ecdsa-sign": { + "rind": 9619.94515641163, + "aws-lc-rs": 12658.112948192207, + "ring": 13677.508216276852, + "rustcrypto": 70619.46936801143, + "graviola": 11491.743408566459, + "libcrux": 95473.90496358377, + "openssl": 18039.115113303404 + }, + "p256-ecdsa-verify": { + "rind": 39246.646351595984, + "aws-lc-rs": 40241.05937461209, + "ring": 41245.17664801874, + "rustcrypto": 226271.69612531402, + "graviola": 41915.14557194227, + "libcrux": 215833.27364464806, + "openssl": 60270.42059642382 + }, + "sha256/64B": { + "rind": 68.73634309272218, + "aws-lc-rs": 95.80266534397508, + "ring": 78.4540520093066, + "rustcrypto": 58.69692797784799, + "graviola": 67.28931677696838, + "libcrux": 384.776632123995, + "openssl": 243.6488777481512 + }, + "sha256/1350B": { + "rind": 619.6597566540065, + "aws-lc-rs": 739.8342337054496, + "ring": 636.9084932117208, + "rustcrypto": 618.3011508283098, + "graviola": 637.447747052195, + "libcrux": 3706.8778584847073, + "openssl": 814.5205447900548 + }, + "sha256/16KB": { + "rind": 6863.9723409473145, + "aws-lc-rs": 6880.156307181569, + "ring": 6966.206626165104, + "rustcrypto": 7223.539010750277, + "graviola": 7075.146686288997, + "libcrux": 43122.66314509489, + "openssl": 7368.629926508486 + }, + "sha512/64B": { + "rind": 138.13699295366257, + "aws-lc-rs": 223.80979537486922, + "ring": 197.65406359745845, + "rustcrypto": 192.25184954840924, + "graviola": 206.12552509449702, + "libcrux": 246.23189746083193, + "openssl": 354.95453149922724 + }, + "sha512/1350B": { + "rind": 1773.053884602435, + "aws-lc-rs": 1899.6373205428117, + "ring": 1868.8132229288826, + "rustcrypto": 1916.513011544336, + "graviola": 1983.8832375521833, + "libcrux": 2942.7170711908766, + "openssl": 1758.556852199972 + }, + "sha512/16KB": { + "rind": 16275.769232284882, + "aws-lc-rs": 25170.169524338704, + "ring": 25380.403789916305, + "rustcrypto": 24121.036569587704, + "graviola": 21044.524431590282, + "libcrux": 29753.72914085865, + "openssl": 15144.828017289788 + }, + "hmac-sha256/64B": { + "rind": 147.08282542276436, + "aws-lc-rs": 264.44167424487074, + "ring": 213.84944184392623, + "rustcrypto": 155.37738405643572, + "graviola": 172.45110715801007, + "libcrux": 851.117463309769, + "openssl": 2573.506360453146 + }, + "hmac-sha256/1350B": { + "rind": 692.1655758802217, + "aws-lc-rs": 852.8591862622461, + "ring": 791.3729510822232, + "rustcrypto": 727.8485167892338, + "graviola": 731.0746161431505, + "libcrux": 4388.70219473396, + "openssl": 3114.361936787851 + }, + "hkdf-sha256/extract-expand": { + "rind": 256.77843103572246, + "aws-lc-rs": 369.138751912449, + "ring": 398.9136826274903, + "rustcrypto": 309.1569061425443, + "libcrux": 1372.3372268081312, + "openssl": 2715.201762164358 + }, + "hkdf-sha256/expand": { + "rind": 88.55041973077404, + "aws-lc-rs": 178.58412059405498, + "ring": 141.81110908086364, + "rustcrypto": 102.81758357792387, + "libcrux": 713.5695952129832, + "openssl": 2000.595353060599 + }, + "rsa2048-pkcs1-sha256-sign": { + "rind": 523170.16244864784, + "aws-lc-rs": 532393.8529599527, + "ring": 523115.8678454263, + "rustcrypto": 1261022.3800000004, + "graviola": 474438.11301019654, + "openssl": 520245.4402674745 + }, + "rsa2048-pkcs1-sha256-verify": { + "rind": 12279.611106776349, + "aws-lc-rs": 14595.468250570844, + "ring": 16560.009867083725, + "rustcrypto": 54057.849893108716, + "graviola": 19246.963751046747, + "openssl": 23585.407318434485 + }, + "rsa2048-pss-sha256-sign": { + "rind": 424296.36024530814, + "aws-lc-rs": 481001.3493039752, + "ring": 471528.3098640461, + "rustcrypto": 1060988.326856805, + "graviola": 448543.1399748781, + "libcrux": 5861217.236666666, + "openssl": 474990.5308940446 + }, + "rsa2048-pss-sha256-verify": { + "rind": 12672.26837110005, + "aws-lc-rs": 15944.49731093201, + "ring": 18030.772341206026, + "rustcrypto": 64699.96485207625, + "graviola": 19628.995570057727, + "libcrux": 312226.193567312, + "openssl": 23601.682021811732 + }, + "mlkem768-keygen": { + "rind": 8432.66958398953, + "aws-lc-rs": 9412.79022225037, + "rustcrypto": 60177.92538052313, + "graviola": 9280.754776095946, + "libcrux": 18145.78183340722, + "openssl": 26821.006628973086 + }, + "mlkem768-encaps": { + "rind": 8529.914702852504, + "aws-lc-rs": 10409.815652726467, + "rustcrypto": 72031.31047074856, + "graviola": 10953.182500105555, + "libcrux": 16033.858618015089, + "openssl": 30019.45323215605 + }, + "mlkem768-decaps": { + "rind": 6068.96540151902, + "aws-lc-rs": 11961.943678535992, + "rustcrypto": 95174.95228440542, + "graviola": 7722.310333481109, + "libcrux": 16215.85387090948, + "openssl": 24635.216524427367 + }, + "p384-ecdh": { + "rind": 179706.50563174227, + "aws-lc-rs": 180488.3124434757, + "ring": 601492.1655652431, + "rustcrypto": 1042109.2816491799, + "graviola": 302571.50348307966, + "openssl": 656670.5430234964 + }, + "p384-ecdsa-sign": { + "rind": 53068.154963526205, + "aws-lc-rs": 97469.15438324642, + "ring": 474636.42304418504, + "rustcrypto": 238313.82929018274, + "graviola": 185154.80296438598, + "openssl": 235522.13648687257 + }, + "p384-ecdsa-verify": { + "rind": 157329.8079119255, + "aws-lc-rs": 199207.40075513523, + "ring": 727104.829428107, + "rustcrypto": 872064.4092921531, + "graviola": 315986.8514703709, + "openssl": 551887.3496098714 + }, + "p521-ecdh": { + "rind": 283912.5756012019, + "aws-lc-rs": 288170.71495049505, + "rustcrypto": 868409.3264873652, + "openssl": 505618.03551943257 + }, + "p521-ecdsa-sign": { + "rind": 58316.217007372376, + "aws-lc-rs": 152351.90711245753, + "rustcrypto": 177472.88751071377, + "openssl": 219598.71526525787 + }, + "p521-ecdsa-verify": { + "rind": 222281.76962809713, + "aws-lc-rs": 327351.2493054529, + "rustcrypto": 610174.982693956, + "openssl": 473663.16028077435 + } + }, + "coverage": { + "AES-GCM": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "none", + "openssl": "none" + }, + "ChaCha20-Poly1305": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "XChaCha20-Poly1305": { + "rind": "none", + "aws-lc-rs": "none", + "ring": null, + "rustcrypto": "none", + "graviola": "none", + "libcrux": "routine", + "openssl": null + }, + "AES header protection": { + "rind": "none", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": null, + "graviola": null, + "libcrux": null, + "openssl": null + }, + "ChaCha20 header protection": { + "rind": "e2e", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": null, + "graviola": null, + "libcrux": null, + "openssl": null + }, + "SHA-256": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "SHA-512": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "HMAC-SHA256": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "HKDF-SHA256": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": null, + "libcrux": "e2e", + "openssl": "none" + }, + "X25519": { + "rind": "e2e", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "routine", + "libcrux": "e2e", + "openssl": "none" + }, + "Ed25519": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "routine", + "libcrux": "e2e", + "openssl": "none" + }, + "P-256": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "P-384": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": null, + "openssl": "none" + }, + "P-521": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": null, + "rustcrypto": "none", + "graviola": null, + "libcrux": null, + "openssl": "none" + }, + "RSA-2048 PSS": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "RSA-2048 PKCS#1": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": null, + "openssl": "none" + }, + "ML-KEM-768": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": null, + "rustcrypto": "none", + "graviola": "routine", + "libcrux": "none", + "openssl": "none" + } + } + }, + { + "name": "Coffee Lake", + "arch": "x86_64", + "source": { + "rind": "f95b91da886bee265dbd836192a7ade2f9158c47", + "cpu": "Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz", + "date": "2026-11-06T15:35:40+00:00", + "versions": { + "rind": { + "rind": "0.1.13", + "rind-rustls": "0.1.13" + }, + "aws-lc-rs": { + "aws-lc-rs": "1.19.0", + "aws-lc-sys": "0.47.0" + }, + "ring": { + "ring": "0.17.14" + }, + "rustcrypto": { + "aes-gcm": "0.11.1", + "chacha20poly1305": "0.11.0", + "sha2": "0.11.1", + "sha3": "0.12.0", + "hmac": "0.13.0", + "hkdf": "0.13.0", + "p256": "0.14.0", + "p384": "0.14.0", + "p521": "0.14.0", + "rsa": "0.10.0-rc.19", + "ml-kem": "0.3.4", + "ed25519-dalek": "3.0.0", + "x25519-dalek": "3.0.0" + }, + "graviola": { + "graviola": "0.4.3", + "rustls-graviola": "0.4.0" + }, + "libcrux": { + "libcrux-aes": "0.0.10", + "libcrux-chacha20poly1305": "0.0.10", + "libcrux-ecdh": "0.0.9", + "libcrux-ecdsa": "0.0.9", + "libcrux-ed25519": "0.0.10", + "libcrux-hkdf": "0.0.9", + "libcrux-hmac": "0.0.9", + "libcrux-ml-kem": "0.0.11", + "libcrux-rsa": "0.0.9", + "libcrux-sha2": "0.0.9", + "libcrux-sha3": "0.0.11" + }, + "openssl": { + "openssl": "0.10.82", + "openssl-sys": "0.9.118", + "rustls-openssl": "0.4.2", + "linked": "OpenSSL 3.5.9 29 Sep 2026 (Library: OpenSSL 3.5.9 29 Sep 2026)" + }, + "tls": { + "rustls": "0.23.46" + } + } + }, + "times": { + "rustls-full-handshake-group/x25519mlkem768": { + "rind": 302425.3520526083, + "aws-lc-rs": 458055.4030323629, + "graviola": 375574.18730899954, + "openssl": 830763.5219240432 + }, + "rustls-full-handshake-group/x25519": { + "rind": 260016.6891345254, + "aws-lc-rs": 369738.7065272647, + "ring": 337912.23527264665, + "graviola": 315727.71180286683, + "openssl": 686500.0513698832 + }, + "rustls-full-handshake-group/secp256r1": { + "rind": 295924.4892655534, + "aws-lc-rs": 417284.4076488843, + "ring": 327879.23115413036, + "graviola": 368788.45385251957, + "openssl": 760039.5912516625 + }, + "rustls-full-handshake-key/ed25519": { + "rind": 213116.54405300232, + "aws-lc-rs": 306109.17607359245, + "ring": 325290.4925387912, + "graviola": 250284.9215959805, + "openssl": 747093.0546327768 + }, + "rustls-full-handshake-key/rsa-2048": { + "rind": 613797.9412501847, + "aws-lc-rs": 758169.1258489729, + "ring": 678162.519692626, + "graviola": 687174.6760218708, + "openssl": 1011129.0454706665 + }, + "rustls-resumed-handshake/x25519": { + "rind": 120947.39610344318, + "aws-lc-rs": 229388.21694202255, + "ring": 199881.5350332496, + "graviola": 159706.19304566277, + "openssl": 496911.0267090291 + }, + "rustls-bulk/aes128-gcm": { + "rind": 440916.7229244865, + "aws-lc-rs": 442543.37513964827, + "ring": 448761.61808039015, + "graviola": 579094.540688636, + "openssl": 491378.9746298212 + }, + "rustls-bulk/aes256-gcm": { + "rind": 544875.5101093543, + "aws-lc-rs": 557856.1804994828, + "ring": 567271.4298847348, + "graviola": 691175.4626954338, + "openssl": 596824.6504625388 + }, + "rustls-bulk/chacha20poly1305": { + "rind": 923821.0274331314, + "aws-lc-rs": 928086.0113994385, + "ring": 925138.9174523422, + "graviola": 1640944.0510526327, + "openssl": 983966.4626097237 + }, + "aes128-gcm/32B": { + "rind": 43.15916603583141, + "aws-lc-rs": 88.83327042566431, + "ring": 70.7040432637589, + "rustcrypto": 100.4982078797696, + "graviola": 71.39229992693309, + "libcrux": 281.52643199369265, + "openssl": 156.06502569144425 + }, + "aes128-gcm/1350B": { + "rind": 246.02047383389657, + "aws-lc-rs": 284.68424193053846, + "ring": 277.1718537592373, + "rustcrypto": 547.3359684291029, + "graviola": 400.38547959209893, + "libcrux": 3492.0898421216825, + "openssl": 352.0939685158669 + }, + "aes128-gcm/16KB": { + "rind": 2334.4852217628627, + "aws-lc-rs": 2416.7381494140714, + "ring": 2381.5094958861264, + "rustcrypto": 5623.335686184604, + "graviola": 3748.933567012662, + "libcrux": 39937.145188229646, + "openssl": 2454.775241588877 + }, + "aes128-gcm-open/32B": { + "rind": 37.590314557027845, + "aws-lc-rs": 90.44863651555588, + "ring": 97.70471186585438, + "rustcrypto": 104.37543397661548, + "graviola": 68.74747100748057, + "libcrux": 303.00757934857927, + "openssl": 159.2243831881219 + }, + "aes128-gcm-open/1350B": { + "rind": 236.2276564130137, + "aws-lc-rs": 284.9516256937142, + "ring": 295.7258335667299, + "rustcrypto": 564.0055590551492, + "graviola": 357.8160965877298, + "libcrux": 3483.286123434034, + "openssl": 354.91888911958904 + }, + "aes128-gcm-open/16KB": { + "rind": 2521.71659881339, + "aws-lc-rs": 2604.2619170092726, + "ring": 2622.3920016863094, + "rustcrypto": 5754.303026968398, + "graviola": 3385.5325872066082, + "libcrux": 41659.90766598408, + "openssl": 2850.8591319399025 + }, + "aes256-gcm/32B": { + "rind": 48.63219847214221, + "aws-lc-rs": 95.44827078228063, + "ring": 74.78119421202508, + "rustcrypto": 107.45554697088258, + "graviola": 77.57315444586634, + "libcrux": 344.01966521589213, + "openssl": 161.41125198066726 + }, + "aes256-gcm/1350B": { + "rind": 325.04493553587355, + "aws-lc-rs": 363.113571055371, + "ring": 352.67454892576404, + "rustcrypto": 622.7591667492841, + "graviola": 475.94126445667405, + "libcrux": 4504.816530396635, + "openssl": 437.1249104404831 + }, + "aes256-gcm/16KB": { + "rind": 3220.4592698100114, + "aws-lc-rs": 3303.462180270266, + "ring": 3246.581706692654, + "rustcrypto": 6449.11698026227, + "graviola": 4711.296547329873, + "libcrux": 50915.71126249938, + "openssl": 3337.0739383617342 + }, + "aes256-gcm-open/32B": { + "rind": 44.725274668504085, + "aws-lc-rs": 101.12041459432034, + "ring": 106.71272146833994, + "rustcrypto": 118.42872126751844, + "graviola": 73.13440095495224, + "libcrux": 363.1440317607148, + "openssl": 171.94263610430872 + }, + "aes256-gcm-open/1350B": { + "rind": 327.8596975138281, + "aws-lc-rs": 422.1055273105423, + "ring": 388.39259220860316, + "rustcrypto": 676.9219616566731, + "graviola": 510.48601034482846, + "libcrux": 4739.299394141973, + "openssl": 642.5886357604636 + }, + "aes256-gcm-open/16KB": { + "rind": 3619.9346652513814, + "aws-lc-rs": 3689.161510288787, + "ring": 3696.405337722827, + "rustcrypto": 7228.291771578484, + "graviola": 4535.667910134297, + "libcrux": 53964.11256859268, + "openssl": 3869.7079673321573 + }, + "chacha20poly1305/32B": { + "rind": 128.96209926130035, + "aws-lc-rs": 148.63147552409362, + "ring": 129.94495030141425, + "rustcrypto": 1207.8771714653647, + "graviola": 231.63900936971268, + "libcrux": 300.8272717631575, + "openssl": 336.90928445056835 + }, + "chacha20poly1305/1350B": { + "rind": 717.8718362847072, + "aws-lc-rs": 754.9897416693576, + "ring": 714.3390966733064, + "rustcrypto": 2181.462194663496, + "graviola": 1292.5933725896593, + "libcrux": 3162.701615269974, + "openssl": 970.6054980099502 + }, + "chacha20poly1305/16KB": { + "rind": 6805.886873589515, + "aws-lc-rs": 6625.198292465067, + "ring": 6602.157467842307, + "rustcrypto": 12605.006180697888, + "graviola": 12516.052884032806, + "libcrux": 35521.47046879754, + "openssl": 6639.492579675878 + }, + "xchacha20poly1305/32B": { + "rind": 255.94624358839874, + "aws-lc-rs": 278.28470484591514, + "rustcrypto": 1267.7367906342872, + "graviola": 335.1466011685066, + "libcrux": 399.6099014667957 + }, + "xchacha20poly1305/1350B": { + "rind": 804.1029905808001, + "aws-lc-rs": 830.9307912291324, + "rustcrypto": 2199.2737054088734, + "graviola": 1320.741652254377, + "libcrux": 3155.0801652135365 + }, + "xchacha20poly1305/16KB": { + "rind": 6384.978947677873, + "aws-lc-rs": 6437.390913112496, + "rustcrypto": 12036.394600265996, + "graviola": 11862.735729037979, + "libcrux": 33416.4320580267 + }, + "quic-header-protection/aes128": { + "rind": 4.729494382784615, + "aws-lc-rs": 9.219408573416422, + "ring": 8.193595624671879 + }, + "quic-header-protection/aes256": { + "rind": 8.08945475590564, + "aws-lc-rs": 10.151336870963895, + "ring": 10.017631695580917 + }, + "quic-header-protection/chacha20": { + "rind": 84.13623177961884, + "aws-lc-rs": 104.426557878368, + "ring": 98.10733701442578 + }, + "x25519-ecdh": { + "rind": 25004.787963523966, + "aws-lc-rs": 30892.438580728456, + "ring": 53601.40291360479, + "rustcrypto": 56594.42607144296, + "graviola": 24951.826177774496, + "libcrux": 72344.68323596539, + "openssl": 55201.871736905036 + }, + "p256-ecdh": { + "rind": 42803.03416052693, + "aws-lc-rs": 51712.30177675976, + "ring": 47104.33772129452, + "rustcrypto": 233699.63260726072, + "graviola": 46439.40340407634, + "libcrux": 280516.9395005172, + "openssl": 81679.15834712576 + }, + "ed25519-sign": { + "rind": 7134.682903317125, + "aws-lc-rs": 7813.749423772228, + "ring": 22257.0981035417, + "rustcrypto": 17402.447694495146, + "graviola": 7218.980862865723, + "libcrux": 53658.31379932023, + "openssl": 31012.152060067416 + }, + "ed25519-verify": { + "rind": 31812.74323551601, + "aws-lc-rs": 31621.224349280175, + "ring": 42476.113091895546, + "rustcrypto": 29876.760500882767, + "graviola": 32219.944445567886, + "libcrux": 69120.42390128566, + "openssl": 93092.35189765459 + }, + "p256-ecdsa-sign": { + "rind": 13109.417715252122, + "aws-lc-rs": 19804.947039751736, + "ring": 14859.16178912369, + "rustcrypto": 69106.18945897574, + "graviola": 19888.31554406187, + "libcrux": 102033.7845963253, + "openssl": 20354.364226087044 + }, + "p256-ecdsa-verify": { + "rind": 41564.618612088074, + "aws-lc-rs": 43268.239697270365, + "ring": 43927.55803310182, + "rustcrypto": 197151.10538298605, + "graviola": 44303.4026627119, + "libcrux": 236872.4229387715, + "openssl": 68341.50379193143 + }, + "sha256/64B": { + "rind": 243.74192885666844, + "aws-lc-rs": 306.88188083946824, + "ring": 276.6111902610443, + "rustcrypto": 473.0203789721238, + "graviola": 576.4609541769788, + "libcrux": 484.8948729635381, + "openssl": 505.1983742111251 + }, + "sha256/1350B": { + "rind": 2456.375506241718, + "aws-lc-rs": 2793.738772876657, + "ring": 2819.161774292229, + "rustcrypto": 5107.477669659855, + "graviola": 6070.69606053635, + "libcrux": 5231.582501769422, + "openssl": 2683.245534636158 + }, + "sha256/16KB": { + "rind": 28061.965542270646, + "aws-lc-rs": 31462.512705155827, + "ring": 32372.720007777683, + "rustcrypto": 58165.022731437326, + "graviola": 69838.79668128007, + "libcrux": 61678.80896497709, + "openssl": 28833.94580942529 + }, + "sha512/64B": { + "rind": 198.4235886351263, + "aws-lc-rs": 228.2357968754158, + "ring": 202.62710255996095, + "rustcrypto": 270.07518962331716, + "graviola": 235.54892663234054, + "libcrux": 288.64081598747975, + "openssl": 430.49633385142823 + }, + "sha512/1350B": { + "rind": 1654.0081870180652, + "aws-lc-rs": 1965.308001445357, + "ring": 1927.6424114639608, + "rustcrypto": 2667.9525447550086, + "graviola": 2348.684070518228, + "libcrux": 3080.598209349293, + "openssl": 1899.4181435668359 + }, + "sha512/16KB": { + "rind": 18531.510923241578, + "aws-lc-rs": 21923.438802486857, + "ring": 21754.002582173995, + "rustcrypto": 30726.478286685386, + "graviola": 27155.492416137135, + "libcrux": 35448.1239756952, + "openssl": 18988.894089607656 + }, + "hmac-sha256/64B": { + "rind": 627.9373574061292, + "aws-lc-rs": 810.6146007160961, + "ring": 706.7051844742713, + "rustcrypto": 1188.229311666718, + "graviola": 1443.937191123711, + "libcrux": 1202.5040738305506, + "openssl": 3689.3177627087334 + }, + "hmac-sha256/1350B": { + "rind": 2791.077117133618, + "aws-lc-rs": 3301.4474802062296, + "ring": 3194.7523254376474, + "rustcrypto": 5798.140309353932, + "graviola": 7050.331034414416, + "libcrux": 6018.83742323943, + "openssl": 5938.467767223289 + }, + "hkdf-sha256/extract-expand": { + "rind": 1150.6968659314043, + "aws-lc-rs": 1436.1870715568284, + "ring": 1312.851635443537, + "rustcrypto": 1976.4316503835814, + "libcrux": 2038.583230603901, + "openssl": 4325.383659961064 + }, + "hkdf-sha256/expand": { + "rind": 299.73459482997856, + "aws-lc-rs": 636.0029119078904, + "ring": 336.58370781835646, + "rustcrypto": 512.4818134580983, + "libcrux": 1010.3524068232288, + "openssl": 2871.9409112333074 + }, + "rsa2048-pkcs1-sha256-sign": { + "rind": 447433.1530116743, + "aws-lc-rs": 448678.3166188858, + "ring": 434466.45943845133, + "rustcrypto": 1144205.9728299098, + "graviola": 445923.1877390276, + "openssl": 453807.564403724 + }, + "rsa2048-pkcs1-sha256-verify": { + "rind": 12880.790081716968, + "aws-lc-rs": 15882.338212629653, + "ring": 16506.21726269642, + "rustcrypto": 57814.73669438586, + "graviola": 19051.281602630414, + "openssl": 24539.279143608688 + }, + "rsa2048-pss-sha256-sign": { + "rind": 445919.6729629082, + "aws-lc-rs": 461869.81302792963, + "ring": 437275.89552238805, + "rustcrypto": 1149823.5205645042, + "graviola": 450243.09732673265, + "libcrux": 7220738.335999998, + "openssl": 456548.6151174819 + }, + "rsa2048-pss-sha256-verify": { + "rind": 14358.929428388468, + "aws-lc-rs": 17005.0660618548, + "ring": 18222.3922694359, + "rustcrypto": 70020.2755831404, + "graviola": 21846.168672917043, + "libcrux": 377869.6554765775, + "openssl": 27155.75481803404 + }, + "mlkem768-keygen": { + "rind": 10239.592799335518, + "aws-lc-rs": 18439.015749685976, + "rustcrypto": 59969.462998965566, + "graviola": 10412.756422628909, + "libcrux": 20052.63081404857, + "openssl": 40627.31846332693 + }, + "mlkem768-encaps": { + "rind": 10614.820658711393, + "aws-lc-rs": 18733.78880855623, + "rustcrypto": 67032.16437810945, + "graviola": 11115.51999376057, + "libcrux": 18131.12620650125, + "openssl": 41180.835585045075 + }, + "mlkem768-decaps": { + "rind": 7072.3352945315855, + "aws-lc-rs": 16014.701270951133, + "rustcrypto": 84369.83066942515, + "graviola": 7419.617415102704, + "libcrux": 19041.955543538497, + "openssl": 31666.407422242617 + }, + "p384-ecdh": { + "rind": 150970.6375018472, + "aws-lc-rs": 174616.41882148662, + "ring": 645537.9080065022, + "rustcrypto": 769611.4819624649, + "graviola": 245237.63439337965, + "openssl": 483502.75231712725 + }, + "p384-ecdsa-sign": { + "rind": 39617.083772030936, + "aws-lc-rs": 82652.59818050834, + "ring": 343155.46700458106, + "rustcrypto": 170636.4857588296, + "graviola": 128636.28886892271, + "openssl": 164533.7649305453 + }, + "p384-ecdsa-verify": { + "rind": 141437.82502260973, + "aws-lc-rs": 175918.628763854, + "ring": 622903.6100546771, + "rustcrypto": 695043.3032067386, + "graviola": 239411.5934003251, + "openssl": 399630.5347628196 + }, + "p521-ecdh": { + "rind": 233755.13159056203, + "aws-lc-rs": 262340.4232904783, + "rustcrypto": 841499.5514615043, + "openssl": 497387.5714969706 + }, + "p521-ecdsa-sign": { + "rind": 64262.896464903206, + "aws-lc-rs": 158671.75802719078, + "rustcrypto": 185926.45505541598, + "openssl": 221002.93849662578 + }, + "p521-ecdsa-verify": { + "rind": 214430.25852815132, + "aws-lc-rs": 303225.93398551794, + "rustcrypto": 636368.6143017586, + "openssl": 460019.67937195214 + } + }, + "coverage": { + "AES-GCM": { + "rind": "e2e", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "none", + "openssl": "none" + }, + "ChaCha20-Poly1305": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "XChaCha20-Poly1305": { + "rind": "none", + "aws-lc-rs": "none", + "ring": null, + "rustcrypto": "none", + "graviola": "none", + "libcrux": "routine", + "openssl": null + }, + "AES header protection": { + "rind": "none", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": null, + "graviola": null, + "libcrux": null, + "openssl": null + }, + "ChaCha20 header protection": { + "rind": "e2e", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": null, + "graviola": null, + "libcrux": null, + "openssl": null + }, + "SHA-256": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "SHA-512": { + "rind": "none", + "aws-lc-rs": "e2e", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "HMAC-SHA256": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "HKDF-SHA256": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": null, + "libcrux": "e2e", + "openssl": "none" + }, + "X25519": { + "rind": "e2e", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "routine", + "libcrux": "e2e", + "openssl": "none" + }, + "Ed25519": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "routine", + "libcrux": "e2e", + "openssl": "none" + }, + "P-256": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "P-384": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": null, + "openssl": "none" + }, + "P-521": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": null, + "rustcrypto": "none", + "graviola": null, + "libcrux": null, + "openssl": "none" + }, + "RSA-2048 PSS": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "RSA-2048 PKCS#1": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": null, + "openssl": "none" + }, + "ML-KEM-768": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": null, + "rustcrypto": "none", + "graviola": "routine", + "libcrux": "none", + "openssl": "none" + } + } + }, + { + "name": "Apple M4", + "arch": "aarch64", + "source": { + "rind": "9e7f6a5a9ea59a0cf1251c24af6c5d4f21c2b0fd", + "cpu": "Apple M4", + "date": "2026-11-07T14:13:32+00:00", + "versions": { + "rind": { + "rind": "0.2.1", + "rind-rustls": "0.23.0" + }, + "aws-lc-rs": { + "aws-lc-rs": "1.19.0", + "aws-lc-sys": "0.47.0" + }, + "ring": { + "ring": "0.17.14" + }, + "rustcrypto": { + "aes-gcm": "0.11.1", + "chacha20poly1305": "0.11.0", + "sha2": "0.11.1", + "sha3": "0.12.0", + "hmac": "0.13.0", + "hkdf": "0.13.0", + "p256": "0.14.0", + "p384": "0.14.0", + "p521": "0.14.0", + "rsa": "0.10.0-rc.19", + "ml-kem": "0.3.4", + "ed25519-dalek": "3.0.0", + "x25519-dalek": "3.0.0" + }, + "graviola": { + "graviola": "0.4.4", + "rustls-graviola": "0.4.0" + }, + "libcrux": { + "libcrux-aes": "0.0.10", + "libcrux-chacha20poly1305": "0.0.10", + "libcrux-ecdh": "0.0.9", + "libcrux-ecdsa": "0.0.9", + "libcrux-ed25519": "0.0.10", + "libcrux-hkdf": "0.0.9", + "libcrux-hmac": "0.0.9", + "libcrux-ml-kem": "0.0.11", + "libcrux-rsa": "0.0.9", + "libcrux-sha2": "0.0.9", + "libcrux-sha3": "0.0.11" + }, + "openssl": { + "openssl": "0.10.82", + "openssl-sys": "0.9.118", + "rustls-openssl": "0.4.2", + "linked": "OpenSSL 3.5.9 29 Sep 2026 (Library: OpenSSL 3.5.9 29 Sep 2026)" + }, + "tls": { + "rustls": "0.23.46" + } + } + }, + "times": { + "rustls-full-handshake-group/x25519mlkem768": { + "rind": 174033.21890941332, + "aws-lc-rs": 212262.18444904193, + "graviola": 179369.13915767695, + "openssl": 463381.0460529038 + }, + "rustls-full-handshake-group/x25519": { + "rind": 151020.41778483818, + "aws-lc-rs": 183413.85142973252, + "ring": 183823.73128491206, + "graviola": 159109.4461157086, + "openssl": 374683.41672971775 + }, + "rustls-full-handshake-group/secp256r1": { + "rind": 171986.33371878232, + "aws-lc-rs": 205844.57167233143, + "ring": 202418.7225171174, + "graviola": 189729.42507314912, + "openssl": 401286.7365568199 + }, + "rustls-full-handshake-key/ed25519": { + "rind": 128510.92569587706, + "aws-lc-rs": 150186.0182503325, + "ring": 154500.49780035467, + "graviola": 123587.1002133885, + "openssl": 383062.41485444066 + }, + "rustls-full-handshake-key/rsa-2048": { + "rind": 372918.13626126794, + "aws-lc-rs": 409148.6252046697, + "ring": 446942.2951440816, + "graviola": 674071.2139057189, + "openssl": 644460.8051278262 + }, + "rustls-resumed-handshake/x25519": { + "rind": 65878.3720542502, + "aws-lc-rs": 89831.04277734383, + "ring": 87174.24632185607, + "graviola": 61633.712907640016, + "openssl": 253423.33819417763 + }, + "rustls-bulk/aes128-gcm": { + "rind": 309220.27200384217, + "aws-lc-rs": 313177.59536131227, + "ring": 372508.70211467415, + "graviola": 333720.4794931284, + "openssl": 340262.9024619477 + }, + "rustls-bulk/aes256-gcm": { + "rind": 348826.2975602187, + "aws-lc-rs": 347022.7329407418, + "ring": 386926.76666469633, + "graviola": 400753.09469779814, + "openssl": 372289.42911777744 + }, + "rustls-bulk/chacha20poly1305": { + "rind": 1108861.0560839367, + "aws-lc-rs": 1098046.0654322447, + "ring": 1096055.1032747156, + "graviola": 1733516.064999999, + "openssl": 1105978.1896970593 + }, + "aes128-gcm/32B": { + "rind": 10.821127131276178, + "aws-lc-rs": 49.69372809937211, + "ring": 41.77351649528646, + "rustcrypto": 23.948854736693, + "graviola": 78.97332920353509, + "libcrux": 51.85918551305852, + "openssl": 66.82372152013478 + }, + "aes128-gcm/1350B": { + "rind": 161.4692060946662, + "aws-lc-rs": 181.14486627588735, + "ring": 210.49577164208878, + "rustcrypto": 212.31663126694232, + "graviola": 215.6740227989241, + "libcrux": 600.2737791776905, + "openssl": 195.70850925735513 + }, + "aes128-gcm/16KB": { + "rind": 1432.566521599921, + "aws-lc-rs": 1443.190547188644, + "ring": 1936.6302916368395, + "rustcrypto": 2264.6464119768475, + "graviola": 1599.8570436429068, + "libcrux": 6780.588489580134, + "openssl": 1513.8319413310687 + }, + "aes128-gcm-open/32B": { + "rind": 12.624156350940789, + "aws-lc-rs": 47.003136652778146, + "ring": 39.2085871220502, + "rustcrypto": 27.56240754679712, + "graviola": 83.92069452651016, + "libcrux": 61.38884540124786, + "openssl": 65.60177198686354 + }, + "aes128-gcm-open/1350B": { + "rind": 177.83539937583888, + "aws-lc-rs": 190.64512582261838, + "ring": 243.23338506305714, + "rustcrypto": 231.7425914327465, + "graviola": 224.74059517980626, + "libcrux": 617.6156645292963, + "openssl": 199.3018164868559 + }, + "aes128-gcm-open/16KB": { + "rind": 1563.0712752137915, + "aws-lc-rs": 1576.9297863990446, + "ring": 2159.982375633808, + "rustcrypto": 2430.9244152697033, + "graviola": 1712.1391089277797, + "libcrux": 6819.108200037708, + "openssl": 1652.8317757636764 + }, + "aes256-gcm/32B": { + "rind": 11.880715452945985, + "aws-lc-rs": 53.39496385912569, + "ring": 44.83910384543195, + "rustcrypto": 24.919444617749757, + "graviola": 78.9991022185664, + "libcrux": 51.81110376903908, + "openssl": 67.0972119067129 + }, + "aes256-gcm/1350B": { + "rind": 188.0371769951236, + "aws-lc-rs": 200.97604078913855, + "ring": 218.6426749137293, + "rustcrypto": 239.1404731163125, + "graviola": 258.09425442053987, + "libcrux": 629.6147367318457, + "openssl": 220.47736031831877 + }, + "aes256-gcm/16KB": { + "rind": 1686.1855233507147, + "aws-lc-rs": 1697.3073911345302, + "ring": 2033.1607276881534, + "rustcrypto": 2628.3458472577004, + "graviola": 2132.9593811962086, + "libcrux": 7077.705491882877, + "openssl": 1767.2597432128607 + }, + "aes256-gcm-open/32B": { + "rind": 13.132106547340127, + "aws-lc-rs": 48.59086319267663, + "ring": 39.39127515955627, + "rustcrypto": 40.837209550139896, + "graviola": 84.25999275576032, + "libcrux": 65.65592334119015, + "openssl": 67.59167122786005 + }, + "aes256-gcm-open/1350B": { + "rind": 196.68958369341146, + "aws-lc-rs": 212.84715434676622, + "ring": 246.73622717744198, + "rustcrypto": 277.79445373680284, + "graviola": 263.0104723684277, + "libcrux": 663.2257057224188, + "openssl": 223.72659071522145 + }, + "aes256-gcm-open/16KB": { + "rind": 1810.1057757052654, + "aws-lc-rs": 1816.3197159097053, + "ring": 2226.9540700569632, + "rustcrypto": 2774.2571486281004, + "graviola": 2194.2861302289434, + "libcrux": 7061.0055906605585, + "openssl": 1934.9325615429348 + }, + "chacha20poly1305/32B": { + "rind": 144.99661678277585, + "aws-lc-rs": 156.82502414329343, + "ring": 144.98987540053835, + "rustcrypto": 340.18897981571126, + "graviola": 193.4348438899373, + "libcrux": 169.92397716752737, + "openssl": 216.07736604064993 + }, + "chacha20poly1305/1350B": { + "rind": 741.085964002363, + "aws-lc-rs": 758.6948909874541, + "ring": 740.7987260163288, + "rustcrypto": 1754.1719231168581, + "graviola": 1206.8867446099468, + "libcrux": 1938.72502933449, + "openssl": 826.046659979804 + }, + "chacha20poly1305/16KB": { + "rind": 7500.009003435792, + "aws-lc-rs": 7498.869139980789, + "ring": 7566.627792079208, + "rustcrypto": 14970.944335894783, + "graviola": 12562.722587372544, + "libcrux": 22123.0659329316, + "openssl": 7367.829055526821 + }, + "xchacha20poly1305/32B": { + "rind": 896.8087247809358, + "aws-lc-rs": 870.5694572603763, + "rustcrypto": 1056.9760977064277, + "graviola": 905.4052495597368, + "libcrux": 899.69902584193 + }, + "xchacha20poly1305/1350B": { + "rind": 1474.1792574479089, + "aws-lc-rs": 1446.5773162934868, + "rustcrypto": 2444.4468967415396, + "graviola": 1939.3436331998216, + "libcrux": 2707.9441152790046 + }, + "xchacha20poly1305/16KB": { + "rind": 8230.331355688439, + "aws-lc-rs": 8308.035252395115, + "rustcrypto": 15592.31772106717, + "graviola": 13217.856057672932, + "libcrux": 22434.145641101422 + }, + "quic-header-protection/aes128": { + "rind": 2.8124206844376203, + "aws-lc-rs": 2.8224564945106345, + "ring": 3.174105868077328 + }, + "quic-header-protection/aes256": { + "rind": 2.9116757067702506, + "aws-lc-rs": 3.002865201930444, + "ring": 3.885372834716827 + }, + "quic-header-protection/chacha20": { + "rind": 57.81215656633907, + "aws-lc-rs": 72.45433722586256, + "ring": 67.37909630635097 + }, + "x25519-ecdh": { + "rind": 16534.54398313712, + "aws-lc-rs": 18119.87452261644, + "ring": 24913.90538684794, + "rustcrypto": 29732.679532732378, + "graviola": 16574.89651544259, + "libcrux": 37295.65352205557, + "openssl": 36212.28886673215 + }, + "p256-ecdh": { + "rind": 26442.616846846267, + "aws-lc-rs": 28797.671124434404, + "ring": 32157.90606908138, + "rustcrypto": 178427.96274124426, + "graviola": 31153.248730604402, + "libcrux": 182720.63488104034, + "openssl": 50383.4029641397 + }, + "ed25519-sign": { + "rind": 3928.3367340926943, + "aws-lc-rs": 4073.116638933698, + "ring": 7029.313147645581, + "rustcrypto": 8646.604429479195, + "graviola": 4206.7317206611915, + "libcrux": 22002.144452912242, + "openssl": 16559.542641495493 + }, + "ed25519-verify": { + "rind": 18807.69500729644, + "aws-lc-rs": 18480.606487365156, + "ring": 20224.85665110093, + "rustcrypto": 18596.90135738947, + "graviola": 18943.19942191887, + "libcrux": 29437.374682598325, + "openssl": 41286.17418077927 + }, + "p256-ecdsa-sign": { + "rind": 7133.358027101757, + "aws-lc-rs": 11160.390583550892, + "ring": 10913.984308126335, + "rustcrypto": 43982.78809537883, + "graviola": 8581.422315004256, + "libcrux": 66945.7074065317, + "openssl": 12433.656889044372 + }, + "p256-ecdsa-verify": { + "rind": 26252.33116518141, + "aws-lc-rs": 27375.722103389442, + "ring": 29221.09328083768, + "rustcrypto": 151686.60569306932, + "graviola": 28178.997641226808, + "libcrux": 156181.1296586375, + "openssl": 41897.571019949755 + }, + "sha256/64B": { + "rind": 36.57131204369449, + "aws-lc-rs": 70.32415830089113, + "ring": 44.0059054981848, + "rustcrypto": 36.215021213239375, + "graviola": 35.29174549586164, + "libcrux": 224.69178580259438, + "openssl": 159.1140555437038 + }, + "sha256/1350B": { + "rind": 408.75800563142957, + "aws-lc-rs": 433.7925322901324, + "ring": 409.5397643251492, + "rustcrypto": 473.4798320161379, + "graviola": 480.237689733539, + "libcrux": 2457.191230657615, + "openssl": 533.0974161064853 + }, + "sha256/16KB": { + "rind": 5008.42772515111, + "aws-lc-rs": 4860.7042243336155, + "ring": 4836.97662563781, + "rustcrypto": 5664.698465090769, + "graviola": 5793.031021274056, + "libcrux": 28996.3705642931, + "openssl": 4980.656088504373 + }, + "sha512/64B": { + "rind": 75.08930666847348, + "aws-lc-rs": 104.75911972741461, + "ring": 84.3027763773294, + "rustcrypto": 76.89690215187275, + "graviola": 174.55049129561593, + "libcrux": 141.6309418697323, + "openssl": 205.1409422183589 + }, + "sha512/1350B": { + "rind": 730.1034595779082, + "aws-lc-rs": 768.3241811440939, + "ring": 742.7614440667948, + "rustcrypto": 723.0342101015636, + "graviola": 1865.7716823478572, + "libcrux": 1562.976879539553, + "openssl": 892.6857567065447 + }, + "sha512/16KB": { + "rind": 8723.8825048475, + "aws-lc-rs": 8911.650822894844, + "ring": 8701.448911755011, + "rustcrypto": 8589.75311976187, + "graviola": 21687.2184971731, + "libcrux": 18393.899450452507, + "openssl": 9332.47374029677 + }, + "hmac-sha256/64B": { + "rind": 109.74123639577842, + "aws-lc-rs": 245.26224879132326, + "ring": 134.0873994885313, + "rustcrypto": 99.42204211376522, + "graviola": 111.56371001464255, + "libcrux": 563.6307050445498, + "openssl": 2094.635672060225 + }, + "hmac-sha256/1350B": { + "rind": 487.068294570858, + "aws-lc-rs": 597.0221645466498, + "ring": 502.1719248680047, + "rustcrypto": 544.7066881230398, + "graviola": 561.8963335065688, + "libcrux": 2796.4507769616566, + "openssl": 2410.3365230935706 + }, + "hkdf-sha256/extract-expand": { + "rind": 225.988738336724, + "aws-lc-rs": 329.65862900862766, + "ring": 272.6824267478671, + "rustcrypto": 211.8131456265796, + "libcrux": 936.1168095769948, + "openssl": 2160.7328722971083 + }, + "hkdf-sha256/expand": { + "rind": 74.11873825998634, + "aws-lc-rs": 153.67865599993996, + "ring": 92.57386320707919, + "rustcrypto": 68.77316440431991, + "libcrux": 481.19385488637937, + "openssl": 1548.2686113032798 + }, + "rsa2048-pkcs1-sha256-sign": { + "rind": 275397.47840204916, + "aws-lc-rs": 283822.6210176839, + "ring": 323015.9733190483, + "rustcrypto": 588222.4770400473, + "graviola": 551435.2627220334, + "openssl": 340402.00488104037 + }, + "rsa2048-pkcs1-sha256-verify": { + "rind": 8409.532015500057, + "aws-lc-rs": 9538.817489825742, + "ring": 11009.06330453941, + "rustcrypto": 30967.695657159747, + "graviola": 18434.44488704374, + "openssl": 16810.763400735595 + }, + "rsa2048-pss-sha256-sign": { + "rind": 275822.7496280971, + "aws-lc-rs": 285360.42448746366, + "ring": 323170.4740904389, + "rustcrypto": 589957.4370858578, + "graviola": 551491.2202231417, + "libcrux": 4467537.258571428, + "openssl": 341811.2497546919 + }, + "rsa2048-pss-sha256-verify": { + "rind": 8742.133543346548, + "aws-lc-rs": 9889.631911130922, + "ring": 11431.395340680452, + "rustcrypto": 38875.21373873208, + "graviola": 18774.058877364416, + "libcrux": 297718.9191606325, + "openssl": 17465.844719457873 + }, + "mlkem768-keygen": { + "rind": 6110.127456215535, + "aws-lc-rs": 7310.531183426925, + "rustcrypto": 26285.603558445397, + "graviola": 6110.241329199627, + "libcrux": 11766.910832510714, + "openssl": 24902.130620043346 + }, + "mlkem768-encaps": { + "rind": 6770.324432036487, + "aws-lc-rs": 7908.032642739922, + "rustcrypto": 27873.441733949516, + "graviola": 6320.086300192737, + "libcrux": 9246.160567412819, + "openssl": 23886.640800354664 + }, + "mlkem768-decaps": { + "rind": 4118.2416762962175, + "aws-lc-rs": 7666.82423372547, + "rustcrypto": 33919.741991691706, + "graviola": 4022.8164635568032, + "libcrux": 9475.755352609887, + "openssl": 24662.710449534505 + }, + "p384-ecdh": { + "rind": 90114.90617576896, + "aws-lc-rs": 104988.2257923255, + "ring": 413703.04707846907, + "rustcrypto": 488307.11447761196, + "graviola": 150929.4916580464, + "openssl": 280830.4326900153 + }, + "p384-ecdsa-sign": { + "rind": 22302.40167796879, + "aws-lc-rs": 49209.360792571795, + "ring": 222336.7691010295, + "rustcrypto": 111888.78847101128, + "graviola": 80216.9928062657, + "openssl": 102688.5455282991 + }, + "p384-ecdsa-verify": { + "rind": 84012.40322594946, + "aws-lc-rs": 110786.01632530417, + "ring": 397214.2813610167, + "rustcrypto": 422125.95016403135, + "graviola": 148924.5971863455, + "openssl": 237682.0304221467 + }, + "p521-ecdh": { + "rind": 129817.85132555047, + "aws-lc-rs": 142271.85765095314, + "rustcrypto": 396279.48286389833, + "openssl": 247042.07350475347 + }, + "p521-ecdsa-sign": { + "rind": 36251.69397908535, + "aws-lc-rs": 84102.4548825181, + "rustcrypto": 80093.55418907935, + "openssl": 132306.58407979904 + }, + "p521-ecdsa-verify": { + "rind": 120989.28014777598, + "aws-lc-rs": 166726.05441185163, + "rustcrypto": 251972.30457711444, + "openssl": 254262.76397024776 + } + }, + "coverage": { + "AES-GCM": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "none", + "openssl": "none" + }, + "ChaCha20-Poly1305": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "XChaCha20-Poly1305": { + "rind": "none", + "aws-lc-rs": "none", + "ring": null, + "rustcrypto": "none", + "graviola": "none", + "libcrux": "routine", + "openssl": null + }, + "AES header protection": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": null, + "graviola": null, + "libcrux": null, + "openssl": null + }, + "ChaCha20 header protection": { + "rind": "e2e", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": null, + "graviola": null, + "libcrux": null, + "openssl": null + }, + "SHA-256": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "SHA-512": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "HMAC-SHA256": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "HKDF-SHA256": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": null, + "libcrux": "e2e", + "openssl": "none" + }, + "X25519": { + "rind": "e2e", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "routine", + "libcrux": "e2e", + "openssl": "none" + }, + "Ed25519": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "routine", + "libcrux": "e2e", + "openssl": "none" + }, + "P-256": { + "rind": "e2e", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "P-384": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": null, + "openssl": "none" + }, + "P-521": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": null, + "rustcrypto": "none", + "graviola": null, + "libcrux": null, + "openssl": "none" + }, + "RSA-2048 PSS": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": "e2e", + "openssl": "none" + }, + "RSA-2048 PKCS#1": { + "rind": "none", + "aws-lc-rs": "none", + "ring": "none", + "rustcrypto": "none", + "graviola": "none", + "libcrux": null, + "openssl": "none" + }, + "ML-KEM-768": { + "rind": "routine", + "aws-lc-rs": "routine", + "ring": null, + "rustcrypto": "none", + "graviola": "routine", + "libcrux": "none", + "openssl": "none" + } + } + } + ] +} diff --git a/src/components/rind/data/runtimes.json b/src/components/rind/data/runtimes.json new file mode 100644 index 0000000..0ae0d75 --- /dev/null +++ b/src/components/rind/data/runtimes.json @@ -0,0 +1,261 @@ +{ + "source": { + "cpu": "Intel(R) Core(TM) Ultra 7 270K Plus", + "core": 2, + "date": "2026-11-07T03:31:02Z", + "load": [7.02, 2.84], + "logical_cpus": 24, + "note": "", + "bun": { + "base": "b1007f1177", + "prototype": "https://github.com/kixelated/bun/compare/b1007f1177...fb621aaac", + "rind": "git ba5ea58e (0.2.0 once released)" + }, + "rounds": 5 + }, + "runs": [ + { + "runtime": "Bun", + "version": "bun 1.4.4 (b1007f117)", + "us": { + "WebCrypto/Ed25519/generateKey": 9.71, + "WebCrypto/Ed25519/importKey pkcs8": 16.13, + "WebCrypto/Ed25519/sign": 12.1, + "WebCrypto/Ed25519/verify": 32.05, + "WebCrypto/Ed25519/exportKey jwk": 8.39, + "WebCrypto/X25519/generateKey": 9.5, + "WebCrypto/X25519/deriveBits": 22.54, + "WebCrypto/P-256/generateKey": 6.1, + "WebCrypto/P-256/importKey pkcs8": 9.84, + "WebCrypto/P-256/importKey spki": 1.04, + "WebCrypto/P-256/sign": 17.79, + "WebCrypto/P-256/verify": 33.18, + "WebCrypto/P-256/exportKey pkcs8": 3.41, + "WebCrypto/P-256/ECDH deriveBits": 31.55, + "WebCrypto/P-384/generateKey": 203.31, + "WebCrypto/P-384/importKey pkcs8": 405.39, + "WebCrypto/P-384/importKey spki": 1.21, + "WebCrypto/P-384/sign": 240.5, + "WebCrypto/P-384/verify": 246.23, + "WebCrypto/P-384/exportKey pkcs8": 16.78, + "WebCrypto/P-384/ECDH deriveBits": 220.8, + "WebCrypto/P-521/generateKey": 491.25, + "WebCrypto/P-521/importKey pkcs8": 981.61, + "WebCrypto/P-521/importKey spki": 1.63, + "WebCrypto/P-521/sign": 585.41, + "WebCrypto/P-521/verify": 607.31, + "WebCrypto/P-521/exportKey pkcs8": 44.22, + "WebCrypto/P-521/ECDH deriveBits": 536.63, + "node:crypto/Ed25519/generateKeyPairSync": 9.39, + "node:crypto/Ed25519/sign": 8.63, + "node:crypto/Ed25519/verify": 28.4, + "node:crypto/Ed25519/sign, PEM key each call": 17.05, + "node:crypto/X25519/generateKeyPairSync": 9.24, + "node:crypto/X25519/diffieHellman": 19.13, + "node:crypto/P-256/generateKeyPairSync": 5.8, + "node:crypto/P-256/sign": 13.97, + "node:crypto/P-256/verify": 29.55, + "node:crypto/P-256/createPrivateKey pem": 5.53, + "node:crypto/P-256/export pkcs8 pem": 3.82, + "node:crypto/P-256/diffieHellman": 27.73, + "node:crypto/P-256/ECDH computeSecret": 31.83, + "node:crypto/P-384/generateKeyPairSync": 203.15, + "node:crypto/P-384/sign": 235.18, + "node:crypto/P-384/verify": 237.78, + "node:crypto/P-384/createPrivateKey pem": 203.98, + "node:crypto/P-384/export pkcs8 pem": 17.23, + "node:crypto/P-384/diffieHellman": 216.99, + "node:crypto/P-384/ECDH computeSecret": 418.07, + "node:crypto/P-521/generateKeyPairSync": 491.46, + "node:crypto/P-521/sign": 577.4, + "node:crypto/P-521/verify": 590.91, + "node:crypto/P-521/createPrivateKey pem": 493.02, + "node:crypto/P-521/export pkcs8 pem": 44.91, + "node:crypto/P-521/diffieHellman": 533.75, + "node:crypto/P-521/ECDH computeSecret": 1022.67 + } + }, + { + "runtime": "Deno", + "version": "deno 2.9.8", + "us": { + "WebCrypto/Ed25519/generateKey": 15.57, + "WebCrypto/Ed25519/importKey pkcs8": 6.2, + "WebCrypto/Ed25519/sign": 13.61, + "WebCrypto/Ed25519/verify": 26.35, + "WebCrypto/Ed25519/exportKey jwk": 8.3, + "WebCrypto/X25519/generateKey": 46.62, + "WebCrypto/X25519/deriveBits": 40.89, + "WebCrypto/P-256/generateKey": 22.79, + "WebCrypto/P-256/importKey pkcs8": 6.75, + "WebCrypto/P-256/importKey spki": 7.11, + "WebCrypto/P-256/sign": 355.73, + "WebCrypto/P-256/verify": 453.16, + "WebCrypto/P-256/exportKey pkcs8": 3.54, + "WebCrypto/P-256/ECDH deriveBits": 443.7, + "WebCrypto/P-384/generateKey": 47.88, + "WebCrypto/P-384/importKey pkcs8": 7.37, + "WebCrypto/P-384/importKey spki": 7.39, + "WebCrypto/P-384/sign": 954.6, + "WebCrypto/P-384/verify": 1231.99, + "WebCrypto/P-384/exportKey pkcs8": 3.36, + "WebCrypto/P-384/ECDH deriveBits": 1229.37, + "WebCrypto/P-521/generateKey": 479.92, + "WebCrypto/P-521/importKey pkcs8": 7.19, + "WebCrypto/P-521/importKey spki": 7.63, + "WebCrypto/P-521/sign": 1382.62, + "WebCrypto/P-521/verify": 1715.57, + "WebCrypto/P-521/exportKey pkcs8": 3.84, + "WebCrypto/P-521/ECDH deriveBits": 1630.18, + "node:crypto/Ed25519/generateKeyPairSync": 12.2, + "node:crypto/Ed25519/sign": 9.57, + "node:crypto/Ed25519/verify": 21.98, + "node:crypto/Ed25519/sign, PEM key each call": 22.56, + "node:crypto/X25519/generateKeyPairSync": 11.84, + "node:crypto/X25519/diffieHellman": 36.05, + "node:crypto/P-256/generateKeyPairSync": 141.32, + "node:crypto/P-256/sign": 304.66, + "node:crypto/P-256/verify": 293.61, + "node:crypto/P-256/createPrivateKey pem": 143.74, + "node:crypto/P-256/export pkcs8 pem": 142.55, + "node:crypto/P-256/diffieHellman": 141.18, + "node:crypto/P-256/ECDH computeSecret": 282.02, + "node:crypto/P-384/generateKeyPairSync": 354.65, + "node:crypto/P-384/sign": 742.48, + "node:crypto/P-384/verify": 711.14, + "node:crypto/P-384/createPrivateKey pem": 358.11, + "node:crypto/P-384/export pkcs8 pem": 356.78, + "node:crypto/P-384/diffieHellman": 354.5, + "node:crypto/P-384/ECDH computeSecret": 708.46, + "node:crypto/P-521/generateKeyPairSync": 442.94, + "node:crypto/P-521/sign": 972.46, + "node:crypto/P-521/verify": 933.21, + "node:crypto/P-521/createPrivateKey pem": 427.16, + "node:crypto/P-521/export pkcs8 pem": 424.53, + "node:crypto/P-521/diffieHellman": 422.35 + } + }, + { + "runtime": "Node", + "version": "node v24.21.0", + "us": { + "WebCrypto/Ed25519/generateKey": 20.8, + "WebCrypto/Ed25519/importKey pkcs8": 18.55, + "WebCrypto/Ed25519/sign": 19.47, + "WebCrypto/Ed25519/verify": 49.95, + "WebCrypto/Ed25519/exportKey jwk": 1.48, + "WebCrypto/X25519/generateKey": 20.12, + "WebCrypto/X25519/deriveBits": 28.46, + "WebCrypto/P-256/generateKey": 19.28, + "WebCrypto/P-256/importKey pkcs8": 31.23, + "WebCrypto/P-256/importKey spki": 21.08, + "WebCrypto/P-256/sign": 31.47, + "WebCrypto/P-256/verify": 55.19, + "WebCrypto/P-256/exportKey pkcs8": 12.01, + "WebCrypto/P-256/ECDH deriveBits": 38.59, + "WebCrypto/P-384/generateKey": 76.43, + "WebCrypto/P-384/importKey pkcs8": 120.59, + "WebCrypto/P-384/importKey spki": 52.77, + "WebCrypto/P-384/sign": 127.42, + "WebCrypto/P-384/verify": 236.7, + "WebCrypto/P-384/exportKey pkcs8": 21.07, + "WebCrypto/P-384/ECDH deriveBits": 164.4, + "WebCrypto/P-521/generateKey": 81.48, + "WebCrypto/P-521/importKey pkcs8": 124.76, + "WebCrypto/P-521/importKey spki": 53.01, + "WebCrypto/P-521/sign": 165.43, + "WebCrypto/P-521/verify": 282.5, + "WebCrypto/P-521/exportKey pkcs8": 20.02, + "WebCrypto/P-521/ECDH deriveBits": 171.6, + "node:crypto/Ed25519/generateKeyPairSync": 15.93, + "node:crypto/Ed25519/sign": 14.93, + "node:crypto/Ed25519/verify": 45.82, + "node:crypto/Ed25519/sign, PEM key each call": 36.04, + "node:crypto/X25519/generateKeyPairSync": 14.84, + "node:crypto/X25519/diffieHellman": 20.88, + "node:crypto/P-256/generateKeyPairSync": 13.15, + "node:crypto/P-256/sign": 15.44, + "node:crypto/P-256/verify": 39.95, + "node:crypto/P-256/createPrivateKey pem": 12.1, + "node:crypto/P-256/export pkcs8 pem": 11, + "node:crypto/P-256/diffieHellman": 32.63, + "node:crypto/P-256/ECDH computeSecret": 60.96, + "node:crypto/P-384/generateKeyPairSync": 67.84, + "node:crypto/P-384/sign": 91.88, + "node:crypto/P-384/verify": 201.2, + "node:crypto/P-384/createPrivateKey pem": 14.95, + "node:crypto/P-384/export pkcs8 pem": 20.18, + "node:crypto/P-384/diffieHellman": 157.76, + "node:crypto/P-384/ECDH computeSecret": 284.47, + "node:crypto/P-521/generateKeyPairSync": 74.17, + "node:crypto/P-521/sign": 131.03, + "node:crypto/P-521/verify": 248.74, + "node:crypto/P-521/createPrivateKey pem": 15.3, + "node:crypto/P-521/export pkcs8 pem": 19.26, + "node:crypto/P-521/diffieHellman": 164.43, + "node:crypto/P-521/ECDH computeSecret": 295.95 + } + }, + { + "runtime": "Bun on rind", + "version": "bun 1.4.4 (fb621aaac)", + "us": { + "WebCrypto/Ed25519/generateKey": 6.18, + "WebCrypto/Ed25519/importKey pkcs8": 5.55, + "WebCrypto/Ed25519/sign": 7.73, + "WebCrypto/Ed25519/verify": 22.87, + "WebCrypto/Ed25519/exportKey jwk": 0.51, + "WebCrypto/X25519/generateKey": 4.58, + "WebCrypto/X25519/deriveBits": 18.05, + "WebCrypto/P-256/generateKey": 6.15, + "WebCrypto/P-256/importKey pkcs8": 9.86, + "WebCrypto/P-256/importKey spki": 1.05, + "WebCrypto/P-256/sign": 17.7, + "WebCrypto/P-256/verify": 33.17, + "WebCrypto/P-256/exportKey pkcs8": 3.45, + "WebCrypto/P-256/ECDH deriveBits": 31.48, + "WebCrypto/P-384/generateKey": 26.45, + "WebCrypto/P-384/importKey pkcs8": 21.86, + "WebCrypto/P-384/importKey spki": 1.56, + "WebCrypto/P-384/sign": 27.39, + "WebCrypto/P-384/verify": 97.03, + "WebCrypto/P-384/exportKey pkcs8": 0.48, + "WebCrypto/P-384/ECDH deriveBits": 84.68, + "WebCrypto/P-521/generateKey": 41.45, + "WebCrypto/P-521/importKey pkcs8": 36.58, + "WebCrypto/P-521/importKey spki": 1.56, + "WebCrypto/P-521/sign": 44.41, + "WebCrypto/P-521/verify": 142.45, + "WebCrypto/P-521/exportKey pkcs8": 0.48, + "WebCrypto/P-521/ECDH deriveBits": 126.57, + "node:crypto/Ed25519/generateKeyPairSync": 5.12, + "node:crypto/Ed25519/sign": 4.54, + "node:crypto/Ed25519/verify": 19.65, + "node:crypto/Ed25519/sign, PEM key each call": 9.21, + "node:crypto/X25519/generateKeyPairSync": 5.02, + "node:crypto/X25519/diffieHellman": 14.27, + "node:crypto/P-256/generateKeyPairSync": 5.83, + "node:crypto/P-256/sign": 13.96, + "node:crypto/P-256/verify": 29.54, + "node:crypto/P-256/createPrivateKey pem": 6.07, + "node:crypto/P-256/export pkcs8 pem": 3.82, + "node:crypto/P-256/diffieHellman": 27.75, + "node:crypto/P-256/ECDH computeSecret": 31.9, + "node:crypto/P-384/generateKeyPairSync": 21.45, + "node:crypto/P-384/sign": 23.72, + "node:crypto/P-384/verify": 93.35, + "node:crypto/P-384/createPrivateKey pem": 22.04, + "node:crypto/P-384/export pkcs8 pem": 0.78, + "node:crypto/P-384/diffieHellman": 81.13, + "node:crypto/P-384/ECDH computeSecret": 81.04, + "node:crypto/P-521/generateKeyPairSync": 36.59, + "node:crypto/P-521/sign": 40.22, + "node:crypto/P-521/verify": 138.48, + "node:crypto/P-521/createPrivateKey pem": 37.58, + "node:crypto/P-521/export pkcs8 pem": 0.9, + "node:crypto/P-521/diffieHellman": 125.26, + "node:crypto/P-521/ECDH computeSecret": 124.84 + } + } + ] +} diff --git a/src/components/rind/data/tally.json b/src/components/rind/data/tally.json new file mode 100644 index 0000000..28be07a --- /dev/null +++ b/src/components/rind/data/tally.json @@ -0,0 +1,32 @@ +{ + "source": { + "pr": "https://github.com/moq-dev/rind/pull/499", + "copied": "2026-11-07" + }, + "as_of": "2026-11-07T14:32:11-08:00", + "scope": "Sessions working in a rind checkout, or whose task names moq-dev/rind, from the graviola bootstrap on 2026-10-27", + "calendar_span": { + "first": "2026-10-27", + "last": "2026-11-07", + "count": 12 + }, + "agent_hours": { + "Claude Code": 559.4 + }, + "maintainer_hours": 28.3, + "tokens_total": 10296083460, + "tokens_by_model": { + "Claude Opus 5.5": { + "input": 505224, + "cache_write_5m": 89635249, + "cache_write_1h": 121853488, + "cache_write_unknown": 0, + "cache_read": 10047912240, + "output": 36177259 + } + }, + "cost_usd_by_model": { + "Claude Opus 5.5": 4158 + }, + "cost_usd_total": 4158 +} diff --git a/src/components/rind/quic.tsx b/src/components/rind/quic.tsx new file mode 100644 index 0000000..91c9661 --- /dev/null +++ b/src/components/rind/quic.tsx @@ -0,0 +1,159 @@ +// QUIC's per-packet crypto: every library's AES-128-GCM seal, as a ball bouncing once per packet. +import { createSignal, For, onCleanup, onMount } from "solid-js"; +import { commit, days, Figure, frames, geomean, midscreen, name, reduced, time, times } from "./chart"; +import data from "./data/libraries.json"; + +type Host = (typeof data.hosts)[number]; +type Size = "32B" | "1350B"; +const seal = (host: Host, size: Size) => host.times[`aes128-gcm/${size}`] as Record; + +// rind's speedup over aws-lc-rs sealing a packet. +const ratio = (h: Host, size: Size) => seal(h, size)["aws-lc-rs"] / seal(h, size).rind; +// Each library's full-packet seal, averaged over every CPU, so no one CPU picks the headline. +const AVERAGE = Object.fromEntries( + data.libraries.map((lib) => { + const ns = data.hosts.map((h) => seal(h, "1350B")[lib]); + if (ns.some((n) => n === undefined)) throw new Error(`libraries.json lacks ${lib}'s seal on a host`); + return [lib, geomean(ns)]; + }), +); +// One bounce is one packet sealed, slowed this much so the eye can follow. +const SLOW = 2e6; + +const table = { + head: ["Library", ...data.hosts.flatMap((h) => [`${h.name}, 32 B`, `${h.name}, 1350 B`])], + rows: data.libraries.map((lib) => [ + name(lib), + ...data.hosts.flatMap((h) => + (["32B", "1350B"] as const).map((size) => (lib in seal(h, size) ? time(seal(h, size)[lib]) : "-")), + ), + ]), +}; + +const source = ( + <> + AES-128-GCM seal, criterion's estimate from rind's benchmark report at {commit(data.source.rind)}, run{" "} + {days(data.hosts)}: {data.hosts.map((h) => `${h.name} is ${h.source.cpu}`).join(", ")}. On a CPU with DIT, rind + holds it across the timed loop, as a caller batching packets does. + +); + +export default function Quic() { + const lanes = Object.entries(AVERAGE).sort((a, b) => a[1] - b[1]); + const [counts, setCounts] = createSignal(lanes.map(() => 0)); + const canvases: HTMLCanvasElement[] = []; + let figure: HTMLElement | undefined; + + // Where a ball sits after `bounces` wall-to-wall trips: 0 at the left wall, 1 at the right. + const at = (bounces: number) => { + const n = Math.floor(bounces); + return n % 2 ? 1 - (bounces - n) : bounces - n; + }; + let elapsed = 0; + const draw = (seconds: number) => { + if (!figure) return; + const style = getComputedStyle(figure); + setCounts( + lanes.map(([lib, ns], i) => { + const canvas = canvases[i]; + const ctx = canvas.getContext("2d"); + const hz = 1e9 / ns / SLOW; + const bounces = seconds * hz; + const n = Math.floor(bounces); + if (!ctx) return n; + const d = devicePixelRatio; + const { width: w, height: h } = canvas; + const wall = 4 * d; + const r = 6 * d; + const x = (p: number) => wall + r + p * (w - 2 * wall - 2 * r); + ctx.clearRect(0, 0, w, h); + ctx.fillStyle = style.getPropertyValue(lib === "rind" ? "--rind" : "--ink-2"); + // A wall flashes for 150 ms after the ball leaves it. + const glow = n > 0 ? Math.max(0, 1 - (bounces - n) / hz / 0.15) : 0; + const hit = n % 2 ? w - wall : 0; + for (const side of [0, w - wall]) { + ctx.globalAlpha = 0.25 + (side === hit ? 0.75 * glow : 0); + ctx.fillRect(side, 0, wall, h); + } + // A short motion trail, then the ball. + for (let k = 6; k >= 0; k--) { + ctx.globalAlpha = k ? (0.3 * (7 - k)) / 7 : 1; + ctx.beginPath(); + ctx.arc(x(at(Math.max(0, bounces - k * hz * 0.018))), h / 2, r * (k ? 0.8 : 1), 0, 2 * Math.PI); + ctx.fill(); + } + ctx.globalAlpha = 1; + return n; + }), + ); + }; + + onMount(() => { + const size = () => { + for (const canvas of canvases) { + canvas.width = canvas.clientWidth * devicePixelRatio; + canvas.height = canvas.clientHeight * devicePixelRatio; + } + draw(elapsed); + }; + size(); + addEventListener("resize", size); + let cancel = () => {}; + onCleanup(() => { + removeEventListener("resize", size); + cancel(); + }); + if (figure && !reduced()) + midscreen(figure, () => { + cancel = frames((seconds) => { + elapsed = seconds; + draw(seconds); + return true; + }); + }); + }); + + return ( +
{ + figure = el; + }} + kicker={`Sealing 1350 B QUIC packets · one core, averaged over ${data.hosts.length} CPUs`} + number={times(AVERAGE["aws-lc-rs"] / AVERAGE.rind)} + headline={ + <> + aws-lc-rs's +
+ packets per core + + } + label={`Packets sealed per second by each library, averaged over ${data.hosts.length} CPUs, drawn as balls bouncing once per packet.`} + table={table} + source={source} + > +
+ + {([lib, ns], i) => ( +
+
+ {name(lib)} + {time(ns)} +
+ { + canvases[i()] = el; + }} + /> +
{counts()[i()].toLocaleString("en-US")}
+
+ )} +
+
+

+ AES-128-GCM, the geometric mean over CPUs.{" "} + {data.hosts.map((h) => `${h.name}: ${times(ratio(h, "1350B"))}`).join(", ")}. aws-lc is Amazon's BoringSSL fork. + On ARM, rind holds DIT (constant-time mode) across each batch. +

+
+ ); +} diff --git a/src/components/rind/runtimes.tsx b/src/components/rind/runtimes.tsx new file mode 100644 index 0000000..2b787dd --- /dev/null +++ b/src/components/rind/runtimes.tsx @@ -0,0 +1,153 @@ +// Asymmetric crypto in Node, Deno, Bun, and a prototype Bun that runs it on rind: one bar per runtime, +// the geomean of its time over every operation they all run, then every operation as a heatmap. +import { createSignal, For, onMount, Show } from "solid-js"; +import { Bands, band, cpu, day, Figure, geomean, midscreen, reduced } from "./chart"; +import json from "./data/runtimes.json"; + +interface Run { + runtime: string; + version: string; + us: Record; // microseconds per call, by `//` +} +const data = json as { + source: { cpu: string; date: string; rounds: number; bun: { base: string; prototype: string }; note: string }; + runs: Run[]; +}; + +const RIND = "Bun on rind"; +const run = (name: string) => { + const r = data.runs.find((r) => r.runtime === name); + if (!r) throw new Error(`runtimes.json has no ${name}`); + return r; +}; +// Every operation timed, in the order timed, and those every runtime runs, for the geomean. +const ALL = [...new Set(data.runs.flatMap((r) => Object.keys(r.us)))]; +const OPS = ALL.filter((op) => data.runs.every((r) => op in r.us)); +const mean = (r: Run) => geomean(OPS.map((op) => r.us[op])); +// Fastest first. +const RUNS = [...data.runs].sort((a, b) => mean(a) - mean(b)); +const MAX = mean(RUNS[RUNS.length - 1]); +const label = (r: Run) => (r.runtime === RIND ? "Bun + rind" : r.runtime); +const us = (v: number) => (v < 1000 ? `${v.toPrecision(3)} µs` : `${(v / 1000).toPrecision(3)} ms`); +const SOURCE = ( + <> + {cpu(data.source.cpu)}, one pinned core, the median of {data.source.rounds} alternating rounds,{" "} + {day(data.source.date)}. {RUNS.map((r) => `${label(r)}: ${r.version}`).join("; ")}. 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. {data.source.note} + +); +const TABLE = { + head: ["Operation", ...RUNS.map(label)], + rows: ALL.map((op) => [op.replaceAll("/", " "), ...RUNS.map((r) => (op in r.us ? us(r.us[op]) : "-"))]), +}; + +export default function Runtimes() { + const rind = mean(run(RIND)); + // Bun + rind's bar starts at stock Bun's length and shrinks once seen. + const [shrunk, setShrunk] = createSignal(false); + let figure: HTMLElement | undefined; + onMount(() => { + if (reduced()) setShrunk(true); + else if (figure) midscreen(figure, () => requestAnimationFrame(() => setShrunk(true))); + }); + + return ( +
{ + figure = el; + }} + kicker={`WebCrypto and node:crypto · geomean of ${OPS.length} calls`} + number={`${(mean(run("Bun")) / rind).toFixed(1)}×`} + headline={ + <> + faster than +
+ stock Bun + + } + label={`Geomean time per call over ${OPS.length} asymmetric crypto operations in ${RUNS.map(label).join(", ")}.`} + table={TABLE} + source={SOURCE} + > +
+ + {(r) => { + const me = r.runtime === RIND; + const width = () => (100 * (me && !shrunk() ? mean(run("Bun")) : mean(r))) / MAX; + return ( +
+
{label(r)}
+
+
+
+
{me ? "fastest" : `${(mean(r) / rind).toFixed(1)}× slower`}
+
+ ); + }} + +
+

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

+
+ ); +} + +// Every operation timed, one row each under its API and algorithm, colored by its time over the fastest +// runtime's. +export function RuntimeHeat() { + const sections = [...new Set(ALL.map((op) => op.split("/", 2).join(" · ")))].map((section) => ({ + section, + ops: ALL.filter((op) => op.split("/", 2).join(" · ") === section), + })); + const fastest = (op: string) => Math.min(...RUNS.filter((r) => op in r.us).map((r) => r.us[op])); + const wins = ALL.filter((op) => band(run(RIND).us[op] / fastest(op)) === 0).length; + + return ( +
+ calls where Bun + rind is fastest, +
+ or within 10% + + } + label={`Time per call for ${ALL.length} asymmetric crypto operations in ${RUNS.map(label).join(", ")}, colored by time over the fastest runtime's.`} + table={TABLE} + source={SOURCE} + > +
+
+
+ {(r) =>
{label(r)}
}
+ + {(s) => ( + <> +
{s.section}
+ + {(op) => ( + <> +
{op.split("/")[2]}
+ + {(r) => ( +
+ + {us(r.us[op])} + +
+ )} +
+ + )} +
+ + )} +
+
+
+ +

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

+
+ ); +} diff --git a/src/components/rind/tally.tsx b/src/components/rind/tally.tsx new file mode 100644 index 0000000..82cd483 --- /dev/null +++ b/src/components/rind/tally.tsx @@ -0,0 +1,97 @@ +// What building rind cost in Opus, as a till receipt: list price, then the subscription that paid for it. +import { For } from "solid-js"; +import { Figure } from "./chart"; +import data from "./data/tally.json"; + +// The Claude subscription that ran every session, in US dollars a month. +const PLAN = 100; + +const MODEL = "Claude Opus 5.5"; + +const tokens = data.tokens_total; +const reads = data.tokens_by_model[MODEL].cache_read / tokens; +const list = data.cost_usd_total; +const paid = (PLAN * data.calendar_span.count) / 30; + +const usd = (n: number, cents = false) => + `$${n.toLocaleString("en-US", { minimumFractionDigits: cents ? 2 : 0, maximumFractionDigits: cents ? 2 : 0 })}`; +const date = (iso: string) => + new Date(`${iso}T12:00:00Z`).toLocaleDateString("en-US", { month: "short", day: "2-digit", timeZone: "UTC" }); + +export default function Tally() { + const lines: [string, string][] = [[MODEL, usd(list)]]; + const stats: [string, string][] = [ + ["Tokens", `${(tokens / 1e9).toFixed(2)}B`], + ["Cache reads", `${Math.round(reads * 100)}%`], + ["Agent hrs", data.agent_hours["Claude Code"].toFixed(1)], + ["Human hrs", data.maintainer_hours.toFixed(1)], + ]; + + return ( +
+ From the final tally in moq-dev/rind#499, through November 7, 2026, at 14:32 PT.{" "} + {data.scope}. Opus usage from Claude Code logs, each API message counted once, priced at its standard API + rate. Paid: {data.calendar_span.count} days of a {usd(PLAN)} a month plan. Human hours are the maintainer's + prompts, with gaps over 15 minutes counted as away. Agent hours cover Claude Code sessions. + + } + > +
+
+
+
RIND
+ {date(data.calendar_span.first).toUpperCase()} → {date(data.calendar_span.last).toUpperCase()}{" "} + {data.calendar_span.last.slice(0, 4)} +
+ {data.calendar_span.count} DAYS · TERMINAL /goal +
+
+ + {([item, cost]) => ( +
+ {item.toUpperCase()} + {cost} +
+ )} +
+
+ + {([item, value]) => ( +
+ {item.toUpperCase()} + {value} +
+ )} +
+
+
+ LIST PRICE + {usd(list, true)} +
+
+ SUBSIDIES + −{usd(list - paid, true)} +
+
+ +
+ {data.calendar_span.count} DAYS OF {usd(PLAN)}/MO · YOU SAVED {Math.floor((1 - paid / list) * 100)}% +
+
+
THANK YOU FOR VIBING
+
+
+
+
+ ); +} diff --git a/src/components/rind/timings.tsx b/src/components/rind/timings.tsx new file mode 100644 index 0000000..6f94f88 --- /dev/null +++ b/src/components/rind/timings.tsx @@ -0,0 +1,112 @@ +// Every operation rind's report times, for every library, colored by its time over the fastest +// library's on each CPU: green is fastest, red is slowest. +import { For } from "solid-js"; +import { Bands, band, commit, days, Figure, name, time, times } from "./chart"; +import json from "./data/libraries.json"; + +const data = json as unknown as { + source: { rind: string }; + libraries: string[]; + sections: { name: string; operations: { id: string; label: string }[] }[]; + hosts: { name: string; source: { date: string }; times: Record> }[]; +}; +type Host = (typeof data.hosts)[number]; + +const ratio = (op: string, lib: string, h: Host) => { + const t = h.times[op]; + return lib in t ? t[lib] / Math.min(...Object.values(t)) : undefined; +}; + +// Libraries with a rustls provider come first, so the rustls rows read as a block on the left. +const tls = data.sections.find((s) => s.name === "TLS 1.3 with rustls"); +if (!tls) throw new Error("libraries.json has no rustls section"); +const rustls = (lib: string) => tls.operations.some((o) => data.hosts.some((h) => lib in h.times[o.id])); +const LIBRARIES = [...data.libraries.filter(rustls), ...data.libraries.filter((lib) => !rustls(lib))]; + +export default function Timings() { + const operations = data.sections.flatMap((s) => s.operations); + // How many of rind's timings are fastest or within 10%, out of how many. + const rs = data.hosts.flatMap((h) => operations.map((o) => ratio(o.id, "rind", h)).filter((r) => r !== undefined)); + const rind = { close: rs.filter((r) => band(r) === 0).length, of: rs.length }; + + return ( +
+ timings where rind is fastest, +
+ or within 10% + + } + label="Every operation rind's benchmark report times, for every library, colored by its time over the fastest library's on each CPU." + table={{ + head: ["Operation", ...LIBRARIES.map(name)], + rows: operations.map((o) => [ + o.label, + ...LIBRARIES.map((lib) => + data.hosts + .map((h) => h.times[o.id][lib]) + .map((t) => (t === undefined ? "-" : time(t))) + .join(" / "), + ), + ]), + }} + source={ + <> + Criterion's estimates from rind's benchmark report at {commit(data.source.rind)}, run {days(data.hosts)}, as{" "} + {data.hosts.map((h) => h.name).join(" / ")}. Every library runs its native path on each CPU. Where the CPU has + DIT, rind holds it across the timed loop, as a caller batching calls does. + + } + > +
+
+
+ {(lib) =>
{name(lib)}
}
+ + {(section) => ( + <> +
{section.name}
+ + {(o) => ( + <> +
{o.label}
+ + {(lib) => ( +
+ + + {(h) => { + const r = ratio(o.id, lib, h); + return r === undefined ? ( + + ) : ( + + ); + }} + + +
+ )} +
+ + )} +
+ + )} +
+
+
+ +

+ Squares: {data.hosts.map((h) => h.name).join(", ")}. Blank: not offered. On ARM, rind holds DIT (constant-time + mode) across each batch. +

+
+ ); +} diff --git a/src/pages/blog/rind.mdx b/src/pages/blog/rind.mdx new file mode 100644 index 0000000..b09e61d --- /dev/null +++ b/src/pages/blog/rind.mdx @@ -0,0 +1,196 @@ +--- +layout: "@/layouts/global.astro" +title: "Cryptography Slop" +author: kixelated +description: I vibe slopped some cryptography, what could go wrong? +cover: "/blog/rind/cover.svg" +date: 2026-11-08 +--- + +import Quic from "@/components/rind/quic"; +import Runtimes, { RuntimeHeat } from "@/components/rind/runtimes"; +import Build from "@/components/rind/build"; +import Coverage from "@/components/rind/coverage"; +import Tally from "@/components/rind/tally"; +import Timings from "@/components/rind/timings"; +import Author from "@/components/author.astro"; +import Meme from "@/components/meme.astro"; + +# Cryptography Slop +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 MoQ build. +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. + +**THIS WILL NOT STAND.** + +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](https://github.com/moq-dev/rind) is vibe slopped crypto. + +rind + +It started as fork of [Graviola](https://github.com/ctz/graviola) and quickly morphed into a monsterish combination of [ring](https://github.com/briansmith/ring) and [aws-lc-rs](https://github.com/aws/aws-lc-rs) and [libcrux](https://github.com/celabshq/libcrux). + +
+ +
Media over QUIC sends a lot of QUIC packets btw
+
+ +^ This is a **big deal** because AES-128-GCM is the most popular TLS cipher suite by far. +Even a tiny reduction in CPU usage has huge impact when multiplied across **every HTTPS request in the world**\*. + +\* this benchmark is HTTP/3 specific. HTTP/1 and HTTP/2 use different payload sizes. +There be a lot of variance depending on the architecture. + +## WOW FAST +Rust gets dunked on for compile speeds but nerds forget that C/C++ can also be terrible when uncached. + +Have you ever tried to cold compile Chromium? +It takes **literal hours**. + +
+ +
i'm a purist
+
+ +Most of the time these builds are cached anyway but IDK it's still nice to see smaller number. + +## Wow fast +Having accomplished my goal of making MoQ faster, I let my 9-year-old gaming PC take a vacation. + + + +lul jk I ran: **/goal**: Support every algorithm, and make it the fastest. + +
+ +
+ +AI is **really fucking good** at benchmarks. +It's terrifying. + +Moments like this fill me with dread as a professional software engineer. +A decade ago, I **wasted weeks** speeding up Go's crypto. I could have just waited a decade for Opus 5.5 instead. +idiot + +## Lean into Lean +I saw an [Anthropic blog post about formal verification](https://www.anthropic.com/research/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? + +
+ +
donate some tokens and make every box green
+
+ +Green boxes are formally verified, dashed are *mostly* formally verified. + +`libcrux` is cool because they try to formally verify everything, but if you saw the last grid, it's super slow. +`rind` will only use a formal proof if the performance was within 10%, which has surprisingly decent coverage. + +**aes-gcm** being verified on some architectures is awesome, because it's the goat of crypto. + +I'm sure we could get **every algorithm formally proven**. +If only there was somebody in the audience works for a **frontier lab** and wants some easy marketting piece instead of stealing all of the glory from 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 common stuff like **TLS certificate generation** in Bun.\ +**Super SLOW**. + +
+ +
rip dino
+
+ +I threw Deprecated Deno in just because it uses RustCrypto. +Oh man, I used to **hate** RustCrypto back when I was a programmer. + +
+ +
Imagine being marginally slower than Node
+
+ +Did the rage bait work? +Login to your work account, choose the secret model nobody else has access to, then `/quest-spawn` to work on [the backlog](https://github.com/moq-dev/rind/tree/main/quest) 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** + +```toml +# safer/faster API +rind = "0.3" + +# if you use ring +ring = { package = "rind-ring", version = "0.17" } + +# if you use rustls +rustls = { version = "0.23", default-features = false, features = ["std", "tls12"] } +rind-rustls = "0.23" + +# if you use aws-lc-rs +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 Opus total was about $4.2k at **API pricing**. +But API pricing is a meme. + +
+ +
Thanks god for the upcoming IPO
+
+ +That's right, **I** 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 with a credit card. + +I know we still need humans to tell the AI to do dumb shit. +Like to rewrite libraries in Rust. + +But like, for how much longer? + + diff --git a/tools/rind/README.md b/tools/rind/README.md new file mode 100644 index 0000000..e7f643b --- /dev/null +++ b/tools/rind/README.md @@ -0,0 +1,41 @@ +# rind post data + +The charts in `src/pages/blog/rind.mdx` read `src/components/rind/data/*.json`. +Each file records its source: the rind commit, host, CPU, and date. +Refresh them all just before posting, from rind main after its latest report collection, then run `just fix`. + +## Build cost and libraries + +Both come from a rind checkout at the commit being announced, after its nightly +`bench` run and `admin/bench-report` collection: + +```bash +bun tools/rind/refresh.ts build # build.json: benchmarks/data/.json's build_cost +bun tools/rind/refresh.ts libraries # libraries.json: every library's times and proofs, labeled by admin/bench-report (needs python3) +``` + +`build` leaves out a host whose report skipped its build cost (a busy host does) and says so; rerun that host's report to bring it back. +`libraries` charts the four hosts in `refresh.ts`'s `HOSTS`, Apple M4 included, timing rind with DIT held across each batch. +`libraries` reads end-to-end proofs from `verified.toml`. Partial proofs, where a proven routine does the core math under unproven glue, live in `refresh.ts`'s `PARTIAL`, by architecture; recheck them against each library's source for each architecture when a locked version changes. + +## Runtimes + +Release-build Bun twice from the same commit, without and with rind (the prototype branch), on an idle host. +Bun's flake ships a rustc whose LLVM trails its clang, and no `nasm`; inside `nix develop`, set `BUN_TOOLCHAIN_RUST` to the nightly in Bun's `rust-toolchain.toml` (rust-overlay has it) and put `nasm` on `PATH` before `bun run build:release`. +Then, there, from this repository: + +```bash +tools/rind/runtimes.sh /build/release/bun /build/release/bun +``` + +Copy `` back, add the two Bun commits and the rind release the prototype builds on (0.2.1 or later) to its `source.json` under `bun`, then: + +```bash +bun tools/rind/refresh.ts runtimes /*.tsv +``` + +## AI tally + +`tally.json` contains the Opus-only subset of the final tally in [moq-dev/rind#499](https://github.com/moq-dev/rind/pull/499), with a `source` naming where it came from. +The maintainer fixed November 7, 2026, at 14:32:11 PT as the stopping point. Keep that cutoff when refreshing the other charts. +The receipt's usage, tokens, and list-price total cover only Claude Opus 5.5. Agent hours cover Claude Code sessions; human hours retain the tally's maintainer estimate. diff --git a/tools/rind/refresh.ts b/tools/rind/refresh.ts new file mode 100644 index 0000000..d924429 --- /dev/null +++ b/tools/rind/refresh.ts @@ -0,0 +1,320 @@ +// Regenerates the rind post's chart data (src/components/rind/data/) from a rind checkout and +// fresh measurements. See README.md beside this file for when to run each step. +// +// bun tools/rind/refresh.ts build benchmarks/data/*.json build_cost +// bun tools/rind/refresh.ts libraries benchmarks/data/*.json times + verified.toml + admin/bench-report +// bun tools/rind/refresh.ts runtimes /*.tsv runtimes.sh's rounds +import { execFileSync } from "node:child_process"; +import { existsSync, readFileSync, writeFileSync } from "node:fs"; +import { join } from "node:path"; + +const DATA = join(import.meta.dir, "../../src/components/rind/data"); + +const read = (path: string) => JSON.parse(readFileSync(path, "utf8")); +const write = (name: string, value: unknown) => { + writeFileSync(join(DATA, name), `${JSON.stringify(value, null, "\t")}\n`); + console.log(`wrote ${name}`); +}; +const today = () => new Date().toISOString().slice(0, 10); +const commit = (rind: string) => execFileSync("git", ["-C", rind, "rev-parse", "HEAD"], { encoding: "utf8" }).trim(); + +// rind's report hosts, named by CPU since the hostnames mean nothing outside. +const HOSTS: Record = { + desktop: "Arrow Lake", + nixos: "Zen 3", + nixos2: "Coffee Lake", + kixtop: "Apple M4", +}; + +// A host whose report skipped its build cost, as a busy one does, is left out and named. +function build(rind: string) { + const hosts = Object.keys(HOSTS) + .filter((host) => existsSync(join(rind, `benchmarks/data/${host}.json`))) + .flatMap((host) => { + const data = read(join(rind, `benchmarks/data/${host}.json`)); + const cost = data.build_cost; + if (cost.status !== "ok") { + console.warn(`left out ${host}: its build cost is ${cost.status} (${cost.reason ?? cost.error})`); + return []; + } + return { + name: HOSTS[host], + source: { + rind: data.commit, + cpu: cost.host.cpu, + jobs: Number(cost.host.jobs), + rustc: cost.host.rustc, + cc: cost.host.cc, + date: cost.started, + runs: cost.runs, + }, + builds: cost.builds.map((b: Record) => ({ + name: b.name, + seconds: b.median_seconds, + cpu_seconds: b.median_cpu_seconds, + bytes: b.stripped_bytes, + tools: b.tools, + packages: (b.packages as string[]).length, + })), + }; + }); + write("build.json", { + source: { rind: commit(rind), file: "benchmarks/data/.json", generated: today() }, + hosts, + }); +} + +// The libraries rind's report times, by its names for them. +const LIBRARIES = ["rind", "aws-lc-rs", "ring", "rustcrypto", "graviola", "libcrux", "openssl"]; +// The post assumes callers hold DIT across a batch, so on a CPU with DIT, rind's time is the report's +// rind-dit-held, which holds it across the timed loop rather than setting it around each call. +const timed = (lib: string) => (lib === "rind" ? ["rind-dit-held", "rind"] : [lib]); + +// The coverage heatmap's rows, matched against report operations without their library. +const COVERAGE = [ + { name: "AES-GCM", pattern: /^aes(128|256)-gcm(-open)?\// }, + { name: "ChaCha20-Poly1305", pattern: /^chacha20poly1305\// }, + { name: "XChaCha20-Poly1305", pattern: /^xchacha20poly1305\// }, + { name: "AES header protection", pattern: /^quic-header-protection\/aes(128|256)$/ }, + { name: "ChaCha20 header protection", pattern: /^quic-header-protection\/chacha20$/ }, + { name: "SHA-256", pattern: /^sha256\// }, + { name: "SHA-512", pattern: /^sha512\// }, + { name: "HMAC-SHA256", pattern: /^hmac-sha256\// }, + { name: "HKDF-SHA256", pattern: /^hkdf-sha256\// }, + { name: "X25519", pattern: /^x25519-/ }, + { name: "Ed25519", pattern: /^ed25519-/ }, + { name: "P-256", pattern: /^p256-/ }, + { name: "P-384", pattern: /^p384-/ }, + { name: "P-521", pattern: /^p521-/ }, + { name: "RSA-2048 PSS", pattern: /^rsa2048-pss-/ }, + { name: "RSA-2048 PKCS#1", pattern: /^rsa2048-pkcs1-/ }, + { name: "ML-KEM-768", pattern: /^mlkem768-/ }, +]; + +// Cells where a proven routine does the core math for at least some of the row's operations, on every +// host of that architecture, under unproven glue, so verified.toml's ✓ doesn't count them. The core is +// the whole cipher, block function, scalar multiplication, NTT, or exponentiation; field arithmetic +// under unproven point formulas, or multiplications under an unproven exponentiation, isn't. Checked +// against each library's source at the version rind's report locks: +// +// - rind: ALGORITHMS.md's tables and Sources, and rind/src/low/mod.rs's per-arch imports. x86_64 runs +// Vale's AES-GCM; aarch64 runs s2n-bignum's AES-GCM kernels in place, outside their proofs, so gets +// none. Both run s2n-bignum's scalar multiplications (p384_montjscalarmul, p521_jscalarmul, +// edwards25519_scalarmul*) and ML-KEM NTT and rejection sampling. aarch64 P-256 and X25519 are ✓. +// - aws-lc-rs (aws-lc-sys 0.47): ec_nistp.h's EC_NISTP_USE_S2N_BIGNUM and curve25519/internal.h's +// CURVE25519_S2N_BIGNUM_CAPABLE take s2n-bignum's X25519, Ed25519, and P-256/384/521 scalar +// multiplications on Linux and Apple, x86_64 and aarch64 alike; mlkem_native_backend.h takes +// mlkem-native's AVX2 or aarch64 backend. aws-lc-verification proves AES-GCM and the AES block on +// x86_64 only, and on aarch64 only SHA-2, whose routine for the SHA-512 instructions (the M4's) ends +// before its store, so neither AES row nor SHA-512 gets credit there. +// - graviola 0.4.4: src/low/mod.rs takes s2n-bignum's X25519, Ed25519, and ML-KEM NTT and base +// multiplication on both architectures. +// - libcrux: portable Rust from HACL*, with no CPU dispatch, so the same on both. +// - ring, RustCrypto, and OpenSSL: none, as verified.toml says. +// +// s2n-bignum's HOL Light proofs cover each of these routines on both architectures (x86/proofs, +// arm/proofs), as do mlkem-native's for its AVX2 and aarch64 backends (proofs/hol_light/). +type Partial = Record>; +const S2N_X86 = "https://github.com/awslabs/s2n-bignum/tree/main/x86/proofs"; +const S2N_ARM = "https://github.com/awslabs/s2n-bignum/tree/main/arm/proofs"; +const SAW = "https://github.com/awslabs/aws-lc-verification/blob/797302470c1703cbb1a3a6fa98daffef0bfd3d80/README.md"; +const MLKEM_X86 = "https://github.com/pq-code-package/mlkem-native/tree/main/proofs/hol_light/x86_64/proofs"; +const MLKEM_ARM = "https://github.com/pq-code-package/mlkem-native/tree/main/proofs/hol_light/aarch64/proofs"; +const LIBCRUX: Partial = { + libcrux: { + "XChaCha20-Poly1305": { + proof: "HACL*'s F* ChaCha20-Poly1305, under an unverified HChaCha20", + link: "https://github.com/hacl-star/hacl-star/tree/main/code/chacha20poly1305", + }, + }, +}; +const PARTIAL: Record = { + x86_64: { + rind: { + "AES-GCM": { + proof: "Vale's F* AES-GCM, for every message without VAES but only short ones with it", + link: "https://github.com/moq-dev/rind/blob/main/ALGORITHMS.md", + }, + Ed25519: { proof: "s2n-bignum's HOL Light scalar multiplications", link: S2N_X86 }, + "P-256": { proof: "s2n-bignum's HOL Light scalar multiplication, for ECDH", link: S2N_X86 }, + "P-384": { proof: "s2n-bignum's HOL Light scalar multiplication, for ECDH", link: S2N_X86 }, + "P-521": { proof: "s2n-bignum's HOL Light scalar multiplication, for ECDH", link: S2N_X86 }, + "ML-KEM-768": { proof: "s2n-bignum's and mlkem-native's HOL Light NTT and sampling", link: MLKEM_X86 }, + }, + "aws-lc-rs": { + "AES-GCM": { proof: "aws-lc-verification's SAW AES-GCM, for AES-256 only", link: SAW }, + "AES header protection": { proof: "aws-lc-verification's SAW AES block, for AES-256 only", link: SAW }, + X25519: { proof: "s2n-bignum's HOL Light X25519 ladder", link: S2N_X86 }, + Ed25519: { proof: "s2n-bignum's HOL Light scalar multiplications", link: S2N_X86 }, + "P-256": { proof: "s2n-bignum's HOL Light scalar multiplication, for ECDH", link: S2N_X86 }, + "P-384": { proof: "s2n-bignum's HOL Light scalar multiplication, for ECDH", link: S2N_X86 }, + "P-521": { proof: "s2n-bignum's HOL Light scalar multiplication, for ECDH", link: S2N_X86 }, + "ML-KEM-768": { proof: "mlkem-native's HOL Light AVX2 NTT and sampling", link: MLKEM_X86 }, + }, + graviola: { + X25519: { proof: "s2n-bignum's HOL Light X25519 ladder", link: S2N_X86 }, + Ed25519: { proof: "s2n-bignum's HOL Light scalar multiplications", link: S2N_X86 }, + "ML-KEM-768": { proof: "s2n-bignum's HOL Light NTT and base multiplication", link: S2N_X86 }, + }, + ...LIBCRUX, + }, + aarch64: { + rind: { + Ed25519: { proof: "s2n-bignum's HOL Light scalar multiplications", link: S2N_ARM }, + "P-384": { proof: "s2n-bignum's HOL Light scalar multiplication, for ECDH", link: S2N_ARM }, + "P-521": { proof: "s2n-bignum's HOL Light scalar multiplication, for ECDH", link: S2N_ARM }, + "ML-KEM-768": { proof: "s2n-bignum's HOL Light NTT and sampling", link: S2N_ARM }, + }, + "aws-lc-rs": { + X25519: { proof: "s2n-bignum's HOL Light X25519 ladder", link: S2N_ARM }, + Ed25519: { proof: "s2n-bignum's HOL Light scalar multiplications", link: S2N_ARM }, + "P-256": { proof: "s2n-bignum's HOL Light scalar multiplication, for ECDH", link: S2N_ARM }, + "P-384": { proof: "s2n-bignum's HOL Light scalar multiplication, for ECDH", link: S2N_ARM }, + "P-521": { proof: "s2n-bignum's HOL Light scalar multiplication, for ECDH", link: S2N_ARM }, + "ML-KEM-768": { proof: "mlkem-native's HOL Light aarch64 NTT and sampling", link: MLKEM_ARM }, + }, + graviola: { + X25519: { proof: "s2n-bignum's HOL Light X25519 ladder", link: S2N_ARM }, + Ed25519: { proof: "s2n-bignum's HOL Light scalar multiplications", link: S2N_ARM }, + "ML-KEM-768": { proof: "s2n-bignum's HOL Light NTT and base multiplication", link: S2N_ARM }, + }, + ...LIBCRUX, + }, +}; + +// The report's operations by section, with their labels, from admin/bench-report itself. +function sections(rind: string): { name: string; operations: { id: string; label: string }[] }[] { + const script = ` +import json, runpy, sys +m = runpy.run_path(sys.argv[1]) +print(json.dumps([ + {"name": name, "operations": [{"id": m["row_name"](op), "label": m["label"](m["row_name"](op))} for op in ops]} + for name, ops in m["SECTIONS"] +]))`; + return JSON.parse(execFileSync("python3", ["-c", script, join(rind, "admin/bench-report")], { encoding: "utf8" })); +} + +// Every library on rind's report hosts: every operation's time, and how much of each coverage row is +// proven: end to end by verified.toml's ✓, a proven core by the host's arch's PARTIAL, or neither. A +// library without the row's operations gets null. +function libraries(rind: string) { + const report = sections(rind); + const verified = Bun.TOML.parse(readFileSync(join(rind, "benchmarks/verified.toml"), "utf8")) as { + verified: { library: string; operations: string[]; arch?: string; cpu?: string[] }[]; + }; + for (const [arch, libs] of Object.entries(PARTIAL)) + for (const [lib, rows] of Object.entries(libs)) + for (const row of Object.keys(rows)) + if (!LIBRARIES.includes(lib) || !COVERAGE.some((c) => c.name === row)) + throw new Error(`PARTIAL names ${arch} ${lib}'s ${row}, which the heatmap lacks`); + + const hosts = Object.entries(HOSTS).map(([host, name]) => { + const data = read(join(rind, `benchmarks/data/${host}.json`)); + if (data.status !== "ok") throw new Error(`${host}'s report is ${data.status}`); + // The report records arm64 as uname says it on macOS; verified.toml and PARTIAL say aarch64. + const arch = ({ arm64: "aarch64", aarch64: "aarch64", x86_64: "x86_64" } as Record)[data.cpu.arch]; + if (!PARTIAL[arch]) throw new Error(`${host}'s arch ${data.cpu.arch} has no PARTIAL`); + const cpu = data.rind_cpu.cpuid as Record; + const results = data.results as { operation: string; library: string; ns: number }[]; + // A report operation as verified.toml names it: "aes128-gcm/{lib}/32B" is "aes128-gcm/32B". + const op = (operation: string) => operation.replace("/{lib}", "").replace("{lib}/", ""); + const has = (feature: string) => { + const flag = feature.replace(/^!/, ""); + if (!(flag in cpu)) throw new Error(`${host} doesn't report CPU feature ${flag}`); + return feature.startsWith("!") ? !cpu[flag] : !!cpu[flag]; + }; + const proven = (lib: string, o: string) => + verified.verified.some( + (v) => + v.library === lib && + (!v.arch || v.arch === arch) && + (v.cpu ?? []).every(has) && + v.operations.some((p) => (p.endsWith("/*") ? o.startsWith(p.slice(0, -1)) : o === p)), + ); + const times = Object.fromEntries( + report + .flatMap((s) => s.operations) + .map(({ id }) => [ + id, + Object.fromEntries( + LIBRARIES.flatMap((lib) => { + const r = timed(lib) + .map((name) => results.find((r) => r.library === name && op(r.operation) === id)) + .find((r) => r); + return r ? [[lib, r.ns]] : []; + }), + ), + ]), + ); + return { + name, + arch, + source: { rind: data.commit, cpu: data.cpu.model, date: data.started, versions: data.libraries }, + times, + coverage: Object.fromEntries( + COVERAGE.map((row) => [ + row.name, + Object.fromEntries( + LIBRARIES.map((lib) => { + const ops = results.filter((r) => r.library === lib && row.pattern.test(op(r.operation))); + if (!ops.length) return [lib, null]; + if (ops.every((r) => proven(lib, op(r.operation)))) return [lib, "e2e"]; + const some = ops.some((r) => proven(lib, op(r.operation))); + return [lib, some || PARTIAL[arch][lib]?.[row.name] ? "routine" : "none"]; + }), + ), + ]), + ), + }; + }); + write("libraries.json", { + source: { + rind: commit(rind), + files: ["benchmarks/data/.json", "benchmarks/verified.toml", "admin/bench-report"], + generated: today(), + }, + libraries: LIBRARIES, + sections: report, + rows: COVERAGE.map((c) => c.name), + partial: PARTIAL, + hosts, + }); +} + +// runtimes.mjs prints `#