Skip to content

Report - #12

Merged
mjthatch merged 27 commits into
mainfrom
report
Nov 13, 2026
Merged

mjthatch merged 27 commits into
mainfrom
report

Conversation

@mjthatch

Copy link
Copy Markdown
Collaborator

No description provided.

mjthatch and others added 27 commits November 12, 2026 16:10
The pages load js/index.js, js/stateless.js and js/stateful.js; the tests and
synth_generated.py run those files instead of cutting the HTML at comment
markers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
formulas.js becomes js/model.js and takes the explorer's security code. The
explorer drops its copy of the cost model and calls slhMetrics; its Schnorr
reference and baseline tuple are the model's SCHNORR and SLH.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
The explorer and the stateful page shared copies of the slider mapping, the
slider and number-input binding, the address-bar code, the share button, the
CSV download and the data.json loader; js/ui.js now holds one of each. Both
pages rank with the model's weightedDistance. The stateful page's entry points
are named like the explorer's: setup, writeHash, applyHash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
renderControls added a click listener to the reset button on every call, and
a reset calls renderControls, so each reset doubled the work of the next one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
The pool comes only from data.json. Without it the page says so and your own
candidate still works. test_site_index becomes test_site_explorer and keeps
the metric checks; the pool count is still checked against data.json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
The pages keep only markup: their <style> blocks move into style.css, and the
fixed inline styles become classes. Rules the pages shared appear once; a rule
that would reach another page is scoped by the body class of its page
(page-index, page-stateful). Rules that matched nothing are gone. Every element
has the same computed style as before, at four widths and on hover and focus.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
docs/model.md derives the hash-call counts, WOTS, SLH-DSA, the FORS security
sum, XMSS, XMSS-MT and UXMSS, and the distance; the scripts point to its
sections. Each script starts with what it does. Only comments and whitespace
change in the scripts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
SHRINCS implements the cached model. The tag uncached-convention, on the
commit before this one, keeps the old numbers reproducible, and the report's
sentence about the HASH_CONVENTION flag now names the tag. The uncached
fixtures and test_uncached_convention go with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
run_experiments.py, utils/all_candidates_search.py and
utils/scatter_plot_draw.py go (decision 4), and with them the README line and
the .gitignore entry for their output. stateful.sage drops the WOTS-classic
variant, which only its own tables showed. costs.sage stops counting hash
calls and grinding attempts (sign_hashes, verify_hashes, exp_search,
worst_search), so the worst_case helper and the scipy import go too; its CSV
loses those four columns.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
The sweep swapped sys.argv to an option costs.sage no longer knows, so every
sweep first computed and printed the whole PARAMETER_SETS table. It now sets
COSTS_SAGE_NO_MAIN, as stateful.sage does. The CSVs are unchanged; make sweeps
sends stdout to /dev/null, so only the time it takes changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
parameters.json holds the stateless grid and size bound, the w sets, the
S_wn table, the stateful grid, the UXMSS bounds, the security target and
the SLH-DSA-128s baseline. costs.sage loads it for the Sage scripts (its
integers become Sage Integers, as literals were), tests/model.py for the
tests, and the export copies it into data.json as before.
test_site_parameters checks the JavaScript model's copies against it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
costs.sage gains evaluate() and sweep(): security, size and costs of every
(w, swn, h, d, k, a) of a grid, with compute_security computed once per
(h, k, a). slhdsa-2to40.sage turns the results into CSV rows and
export_site_data.sage into pool rows; their own copies of the loop, the
security cache and the scheme-to-model rule are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
XMSS is XMSS-MT with d = 1, so its rows come from the same functions and
the copies for a single tree go. The WOTS chain counts come from
wots_lengths() in costs.sage instead of three local copies of the FIPS 205
formulas. Arguments are parsed in the main block, so export_site_data.sage
no longer swaps sys.argv to load the file, and --help prints this file's
docstring, not costs.sage's.

Removed: the --ref-size20 and --ref-size40 flags, which nothing read, and
the reference footer with its hard-coded 128-bit security; the UXMSS table
note names the reference instead. The table headers list w = 65536 too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
docs/model.md gains the W+C, FORS+C and PORS+FP sizes and costs, how mmax
is chosen, the PORS+FP forgery probability, how security.sage sums, and
why hsf stops at 255. The code keeps one-line pointers: security.sage's
70-line essay, the WOTS-TW and WOTS+C derivations in costs.sage and the
hash-call notes go.

Module headers are at most ten lines: what the file computes, from what,
and how to run it. slhdsa-2to40.sage prints its options from a USAGE
string. Removed: history (the audit, "the old formula"), emphasis,
decorative separators and comments that repeat the code. Fixed: the
security.sage demo is SLH-DSA-128s, not 128f; the export header named
(w, S_wn) pairs and a --max-size that parameters.json now holds;
compute_security gets n from costs.sage, and the security target in the
costs.sage assertion and the sweep summary comes from parameters.json.
tests/model.py has one ν function instead of two.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
Each script opens with what it draws or writes, from which input, and how
to run it; sieve_search_draw.py had no header. Removed: step numbers and
comments that repeat the code, a commented-out title, "NEW LOGIC" banners
and the history of the focus figures. min_mult_search.py compares five
metrics, not four. sieve_search_draw.py's default weights were never used,
since --weights always sets them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
The root held the model, the pipeline, third-party code and a historical
script side by side (decision 3). Now:

  model/        costs.sage, security.sage, stateful.sage
  scripts/      slhdsa-2to40.sage, export_site_data.sage
  analysis/     the five scripts of utils/ and the four sweep CSVs
  third_party/  octopus_pmf.py
  reference/    original-sphincs-parameter-search.sage

The Sage files take the repository root as the folder above the script that
was started (load() keeps its __file__) and import octopus_pmf from
third_party/. The Makefile, CI's paths and cache key, .gitignore, the tests,
docs/model.md, the README links, the report's mention of the sweep script
and the explorer's link to security.sage follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
tests/test_regression.py held 21 tests of four kinds in 640 lines. They
move unchanged into test_model.py, test_generated.py, test_site.py and
test_sage.py; the paths, fixtures and helpers they share go to common.py.
tests/run.py runs all of them, or the areas named, without pytest
(decision 9), and pytest still collects the same 21 tests. The Makefile,
CI, the README and the fixtures' note name the new runner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
GitHub removed Node 20 from its runners on 23 September 2026, so the
actions still built for it ran on Node 24 with a warning each. Every action
moves to its latest major, all of which declare node24: checkout v7, cache
v6, upload-artifact v7, download-artifact v8, setup-python v7, setup-node v7,
upload-pages-artifact v5, deploy-pages v5 and action-gh-release v3.
latex-action stays on v3, a composite action with no Node runtime.
Neither workflow triggers on the stateful branch, which no longer exists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
358 lines, about 300 of them from a LaTeX template for packages the report
does not use (glossaries, beamer, pythontex and the like), become 28: the
Python, Node and Sage caches, what make generate writes, and the report's
pdflatex, bibtex and latexmk files. A full generate, a report build, make
check-local and the site snapshot leave git status clean, and no tracked
file is ignored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
…nect

The README listed files. It now says what the project answers and links
the site, the report and the blog post; gives units and the hash model in
one paragraph; starts without Sage (make check-local) and with it (make
generate), naming what each make step reads and writes; lists the folders;
and says how to update the fixtures and when to run the site snapshot,
which stays a local check (decision 7).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
…n appendix

The recommended candidate tuple moves out of 3-search.tex, which held three
quarters of the report, into content/4-candidate.tex. The hash-cost
convention and the three "Note:" paragraphs (average and worst case,
normalization within the feasible region, SHRINCS framing) move to
appendices A to D after the references. The body keeps one sentence for
each with a reference to its appendix, so it still reads on its own. The
closing paragraph on make generate and the explorer moves to the Toolset
subsection. The text is otherwise unchanged; the numbers in the PDF differ
only in section and page numbers and the new pointer sentences.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
The sieve figures name their stages Size, KeyGen, SigGen, SigVer and ρ
instead of "KG", "SG", "VF", "C/B" and "Signature Verification", the
concept scatter plots Size against SigGen, and the focus figures spell
"Metric-Normalized" as the report does. The unused "title" of each sieve
stage goes. Twelve figures change their labels; sieve_step1_initial.png,
concentric_diagram.png, the CSVs and site/data.json stay byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
The report named each metric several ways: key generation cost, Keygen
and KeyGen; signing cost and SigGen; SigVerify, verification cost and
SigVer; compressions per byte, C/B, Comp/Byte and ρ. The metric list, the
filters, the six tables, the sub-captions of the sieve figure and the
weights now use the site's glossary: Size (B), KeyGen, SigGen and SigVer
(C), and ρ (C/B). Running text keeps plain English where it describes
rather than names a metric. The numbers in the PDF are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
Facts:
- The introduction gave 324 bytes, from the title of the Delving Bitcoin
  post, for the smallest stateful signature. The SHRINCS reference
  implementation's first stateful signature is 548 bytes (w = 16); the
  sentence says so and links the implementation.
- The balanced candidate saves 13% of the size (6,800 against 7,856 B),
  not 12%.
- Fewer layers make each tree taller, which costs exponentially more hashes
  at key generation; the height itself does not grow exponentially.
- The sieve example no longer compares itself with a w grid of an earlier
  version of the report.

Grammar: the recommended-candidate paragraph, three sentences without a
verb, two captions, spaced hyphens as dashes, and American spelling
throughout (normalized, color, behavior, favors, standardizes, key pair).
The authors' wording is otherwise unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
…d framed

No section draws with tikz or uses framed. tikz was the only package that
loaded xcolor, which the coloured cells of Table 1 and the link colour need,
so xcolor is loaded directly. xurl lets the long Delving Bitcoin URL break,
which removes the underfull box in the references. The title block names
Blockstream Research as the author, and the six [h!] floats ask for [!ht],
the placement LaTeX already substituted with a warning. The log now has no
warnings, and the numbers in the PDF are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QabhpThuWQEq1AZRZo24vm
@mjthatch
mjthatch merged commit 03949dd into main Nov 13, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant