CoolFace
Datasetpublic

nickh007/hw-verify

hw-verify โ€” a hardware-security verification dataset with controls Every positive example ships beside a deliberately broken counterpart, so a model or tool is graded against controls instead of against itself. Try the checker that generated this data: ๐Ÿ”’ hw-verify Space โ€” paste Verilog, get a verdict, in your browser, no install. Install pip install datasets 30-second quickstart from datasets import load_dataset rtl =โ€ฆ See the full description on the dataset page: https://huggingface.co/datasets/nickh007/hw-verify.

sourceHugging Faceapache-2.0updated 2mo agoView on Hugging Face
0likes52downloads
Dataset Card

hw-verify โ€” a hardware-security verification dataset with controls

Every positive example ships beside a deliberately broken counterpart, so a model or tool is graded against controls instead of against itself.

![License](#licence) ![Records](#splits) ![Splits](#splits) ![Reproducible](#provenance)

Try the checker that generated this data: ๐Ÿ”’ hw-verify Space โ€” paste Verilog, get a verdict, in your browser, no install.

Install

bash
pip install datasets

30-second quickstart

python
from datasets import load_dataset

rtl = load_dataset("nickh007/hw-verify", "rtl_constant_time", split="test")
print(rtl.num_rows, "records,", len(rtl.column_names), "fields")

scored = rtl.filter(lambda r: r["scored"])
print(scored[0]["module"], scored[0]["label"])
console
27 records, 12 fields
barrett_ct CONSTANT_TIME

The result that motivates the whole corpus โ€” probes a dependence-only tool would flag:

python
masking = load_dataset("nickh007/hw-verify", "masking_probes", split="test")
uniformity_only = masking.filter(lambda r: r["certificate"] == "uniformity")
print(len(uniformity_only), "probes certified ONLY by uniformity")
console
2 probes certified ONLY by uniformity

Why this exists

Security datasets in this area are almost always one-sided: a pile of vulnerable examples. A classifier that answers "vulnerable" for everything scores 100% on such a corpus, and nobody notices.

Every split here is matched. The RTL split pairs each constant-time design with a leaky twin of identical module interface. The masking split includes three gadgets that genuinely recombine a secret. The patch split includes a fix that blocks only one witness and a fix that rejects everything. If your method cannot separate the halves of a pair, its accuracy number means nothing.

Provenance

Every record is computed, not transcribed. build.py reads the actual fixture sources, runs the actual masking prover over every probe, and runs the actual solver to produce the patch certificates. Re-running it reproduces the committed files byte for byte, and a test asserts that โ€” so the data cannot silently drift from the code that produced it.

bash
python build.py --check    # fails if the committed data is stale

The tools that generated it are open: `ctbench`, `ct-mask`, `patchproof`.

Splits

rtl_constant_time โ€” 27 records

Verilog-2001 fixtures. 18 scored across 8 matched pairs, plus 9 unscored files kept for context (fault-detection and secret-residue designs whose observable is a data output, so grading them under a timing task would be a category error).

FieldTypeMeaning
filestringfixture file name
modulestringtop-level module name
sourcestringcomplete Verilog-2001 source
scoredboolpart of the graded task
labelstring \nullCONSTANT_TIME, LEAKY, or null when unscored
observationstring \nullcompletion signal the label is about
secretslist[string]inputs declared secret โ€” never inferred
pairstring \nullmatched-pair group
rolestring \nullpositive, negative, repaired, out_of_remit
notestringwhat the fixture demonstrates
reasonstring \nullwhy an unscored fixture is unscored
licensestringCC-BY-4.0, or ISC for the picorv32 derivatives

The out-of-remit control. barrett_buggy.v is genuinely constant-time and functionally wrong โ€” a miscalibrated Barrett shift makes 62,206 of 65,536 coefficients disagree with the reference. A timing tool that flags it is crying wolf. It is labelled role: out_of_remit and it exists to separate serious methods from pattern-matchers.

masking_probes โ€” 17 records

One record per probe wire of every bundled masked gadget, with the certificate that discharged it. Probe-level rather than gadget-level because the interesting datum is which certificate covered which wire.

FieldTypeMeaning
gadgetstringgadget name
gadget_expected / gadget_verdictstringSECURE or LEAKY
probestringthe internal wire an adversary probes
secureboolwhether this probe is certified
certificatestring \nulldependence, uniformity, or null if neither applies
refreshed_bystring \nullthe fresh mask, for a uniformity certificate
touches_sharesstring (JSON)secret โ†’ shares the probe depends on
secret_classesintclasses in the modelled-leakage enumeration
mean_invariant / distribution_invariantbooltwo separate determinations
modelstringthe leakage model the verdict is stated under

The result that motivates the tool: two dom_and probes certify only by uniformity. They touch both shares of an operand โ€” so a dependence-only analysis flags them โ€” and are perfectly secure because a fresh mask always flips them.

Note that mean_invariant and distribution_invariant are recorded separately. For dom_and the mean is invariant and the distribution is not. A first-order verdict is a statement about the first moment, and the data says so rather than letting you assume more.

patch_certificates โ€” 5 records

Modelled bounds-check defect classes, with exploit witnesses and replayable elimination certificates.

FieldTypeMeaning
defect_classstringA, B, C, or a *-badfix / *-vacuous demo
titlestringone-line description of the defect shape
is_demobooltrue for the deliberately-wrong demonstrations
verdictstringCOMPLETE, INCOMPLETE, or VACUOUS
widths / total_widthstring (JSON) / intdeclared machine widths
exploit_witnessstring (JSON) \nullan input the original guard admits that violates safety
incompleteness_witnessstring (JSON) \nullan input the corrected guard still admits
violating_region_measureint \nullexact count, when the space is small enough to enumerate
bit_precise_legbooldischarged at the declared machine widths
elimination_certificatestring (JSON) \nullFarkas multipliers
certificate_replays_without_solverbool \nullre-checked by integer arithmetic alone
legs_agreebool \nullbit-precise and elimination legs concur
strictly_stronger_than_unsound_guardbool \nullthe fix implies the original guard and rejects more, so the elimination is non-vacuous
out_of_modelstring (JSON)defect shapes a COMPLETE verdict does not cover

Baseline

data/baseline.json holds a reference result for the RTL split from the bundled cone-of-influence checker: 18/18 correct, 8/8 pairs separated, sound, out-of-remit control passed. It is a baseline, not a strong tool โ€” it reasons about syntax rather than semantics and will over-report on designs where a secret reaches a completion signal by a path never taken.

Usage

python
from datasets import load_dataset

rtl = load_dataset("nickh007/hw-verify", "rtl_constant_time", split="test")
scored = rtl.filter(lambda r: r["scored"])
print(scored[0]["module"], scored[0]["label"])

masking = load_dataset("nickh007/hw-verify", "masking_probes", split="test")
uniformity_only = masking.filter(lambda r: r["certificate"] == "uniformity")
print(len(uniformity_only), "probes a dependence-only tool would flag")

Scoring โ€” do not use plain accuracy

The two error directions are not equally bad, and the reference implementation ranks accordingly:

OutcomeMeaningWeight
unsoundsaid safe, is leakyships a vulnerability โ€” dominates the ranking
imprecisesaid leaky, is safecosts engineering time
abstainedreturned UNKNOWNneither correct nor unsound

pip install ctbench gives you ctbench score, ctbench validate, and ctbench leaderboard, which implement exactly this rule.

Scope and limits

  • โ€”RTL labels concern completion timing against declared secrets โ€” not power, EM, cache, or microarchitectural channels.
  • โ€”Masking records are glitch-free gate-value probing, first order (d=1), 2-share.
  • โ€”Patch records are reachability in modelled bit semantics โ€” not an RCE claim. The out_of_model field lists the defect shapes deliberately excluded.
  • โ€”Secrets are a specification choice, recorded per fixture and never inferred from source.

<!-- portfolio:start -->

Part of the hw-verify toolkit

Five open tools, a dataset, and a browser demo for proving security properties of hardware and bounds checks. They share one boundary: everything open analyses a design you disclose in full.

ProjectWhat it does
**Docs & overview**What the toolkit proves, and what it refuses
โ–ถ [Live demo](https://huggingface.co/spaces/nickh007/hw-verify)Try the constant-time checker in your browser โ€” runs the real analyzer via Pyodide
`ctbench`Matched-pair constant-time RTL benchmark + leaderboard
`patchproof`Prove a bounds-check fix eliminates every violating input
`ct-mask`First-order masking verification by two certificates
`hw-verify-mcp`MCP server โ€” all three checkers, callable by AI agents
`ct-audit-action`GitHub Action โ€” fail a PR on a leaky completion signal
`hw-verify` dataset (you are here)49 records, 3 splits, byte-reproducible from these tools
`hw-verify-static` ยท `hw-verify-space`Source for the live demo (Pyodide) and a fuller Gradio build

The commercial boundary. Proving a property to a third party who never receives the design โ€” a verdict bound to a commitment of a design that stays hidden โ€” is a different problem and a commercial one. It is not in any of these packages. <!-- portfolio:end -->

Licence

Per record, in the license field, because flattening it would misstate it. Full texts and the upstream copyright notice are in `LICENSE-DATA`:

  • โ€”CC-BY-4.0 โ€” RTL fixtures, so they can be copied into papers and slides.
  • โ€”ISC โ€” pcpi_div.v, pcpi_mul.v, pcpi_div_wiped.v, pcpi_div_halfwipe.v, which derive from the picorv32 project by Claire Wolf and remain under the upstream licence.
  • โ€”Apache-2.0 โ€” the masking and patch records, which are outputs of the tools.

Citation

bibtex
@misc{hwverify2026,
  title  = {hw-verify: a hardware-security verification dataset with matched controls},
  year   = {2026},
  note   = {Matched-pair RTL, masking probe certificates, and patch-completeness certificates}
}

Contributing

The most valuable contribution is a new matched pair for the corpus: a safe design and a leaky twin with an identical interface, so the pair cannot be won by guessing. See ctbench's CONTRIBUTING โ€” every record here is regenerated from that corpus by build.py, so a fixture added there appears here on the next build.

The commercial boundary

Everything here concerns designs disclosed in full. Proving a property to a third party who never receives the design is a different problem โ€” it requires the verdict bound to a commitment of a design that stays hidden โ€” and that capability is commercial.