Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion certificates/partial-swap-network.json
Original file line number Diff line number Diff line change
Expand Up @@ -1481,7 +1481,7 @@
"scripts/partial_swap/match_positive_dag.cpp": "8a6d64e2d0ac2c69210fb0b8a5bd0d714ad40b3609f75a5fddfcba3291a3d552",
"scripts/partial_swap/paired.py": "ddcecace3a8e04d690914cbd64873ab8dde8c0c3477a255767b0ed6f639bb0c7",
"scripts/partial_swap/positive.py": "1dadf771226d6e4f3bf9ce3aae2e6a2ad7173f4d1c900299d0663fc4c432f3e8",
"scripts/partial_swap/shared.py": "7290bd639600aecff11941d3faf95c9ce95589125cc6a7f7440fb86af7a0f17c",
"scripts/partial_swap/shared.py": "5a0646a50b9f3e8ea55168620a78e8853b0ab810517cefc8cfb8696aedee278a",
"scripts/partial_swap_network.py": "acdd81b4dea2815f8838a0c3ea8ac4968f2bc13fd7c99173473d865779096782",
"scripts/partial_swap_producer.py": "dba07d742c68e8e4aedd1d93fc4c47a0481778268f7480997463e2b269fdd0a0"
},
Expand Down
94 changes: 94 additions & 0 deletions docs/research/partial-swap-retained-total-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Restore retained-total partial-swap verification

This is a verifier regression fix, with no new κ or runtime-speedup claim.
The reviewed starting tree is `20ecf2891d80b5acf18d980b2164fb44ea7faa90`.

`partial_swap.graph.graph(h)` adds the local empty-exclusion output `()`.
`SharedPointCircuit` lifts that output to the singleton target `(common,)`,
representing a retained full pair-star total. The digest optimization introduced
in [PR2039](https://github.com/CrocSwap/integer-mult-bounds/pull/2039) unpacks
all targets as triples. Consequently even `graph(6).verify()` raises
`ValueError: not enough values to unpack (expected 3, got 1)`. The h25 producer
used by `make copied-fixed-reversed-producer` and `make verify` fails there too.
Existing equivalence tests constructed exclusion-only graphs, missing this case.

The repair joins the target's integer entries with commas inside the same JSON
array delimiters. For both singleton and triple targets these are exactly the
bytes emitted by the historical `json.dumps(..., separators=(',', ':'))`
verifier. Sorted traversal, newline boundaries, node encoding, topology,
disjointness, support, core and union assertions are unchanged.

New tests compare whole receipts to the pre-optimization verifier on retained-total
graphs of sizes 6, 8, 10 and 25, and compare h25 against the frozen
`research/copied-fixed-reversed/producer-input-25.json` scalar receipt. A negative
control replaces a full retained total with a proper excluded-pair sum and
requires both verifiers to reject it. Existing exclusion-only equivalence and
support-corruption controls remain in place.

The live partial-swap certificate is regenerated with its own generator. Exactly
one source hash changes; all mathematical values remain byte-identical. The two
existing optimization test suites and package verifiers bind the repaired source
hash. Their frozen baseline files, provenance manifests, performance receipts,
and historical source commits remain unchanged. No archived mathematical
certificate or expected circuit digest is edited.

## Reproduction

From the repository root, with Python 3.12 (the producer also needs a C++17 compiler):

```sh
python3.12 -B scripts/partial_swap_network.py
python3.12 -B -m unittest discover -s tests -p 'test_partial_swap*.py'
python3.12 -B scripts/research_package.py --package research/partial-swap-digest
python3.12 -B scripts/research_package.py --package research/partial-swap-init
make copied-fixed-reversed-producer
```

The package checks include h46 receipt equivalence, optimized-Python digest
checks and certificate pin-only comparisons. Production support assertions are
historically disabled by `python -O`; the negative controls run without `-O`.
This repair does not alter that inherited interface.

## Validation on the repaired source

- Python 3.14.7 focused suite: 16 tests pass, including the new negative control.
- Python 3.12.11 registered `partial-swap-digest` and `partial-swap-init`
packages: both pass their complete normal/optimized verification and tests.
- `make copied-fixed-reversed-producer`: exit 0. Fresh h25 DAG, all 96,273
distinct matrix profiles, five-prime reconstruction, positive labels,
matching and the separate copied CRT audit pass.
- `make verify`: exit 2 after the repaired producer and full geometry checks
pass. The next historical witness rejects its old source pin (see below).
- `git diff --check`: pass.

The unchanged h25 scalar digest is
`69283632099c012ae00cf1e9ab5b1f0757912944ff0708aa6cbf7633d841fd88`;
the exported DAG hash is
`ab28c3eba56b4b494f659b833c5aba4bb3e1e2225c3294411edf51a3999f1d03`.
The repaired source hash is
`5a0646a50b9f3e8ea55168620a78e8853b0ab810517cefc8cfb8696aedee278a`.

The broad historical sweep next fails in
`research/copied-fixed-reversed/witness.py:verify_sources`: its frozen manifest
requires `shared.py` hash `81e9af92cdf38243a540cdcff2062778e449467848d444da37a9553c12ca4c34`,
whereas pinned main already contains
`7290bd639600aecff11941d3faf95c9ce95589125cc6a7f7440fb86af7a0f17c`.
Comparing the manifest and source directly at the pinned main commit confirms
this mismatch predates this repair. The manifest remains unchanged; this PR does
not claim that the complete historical sweep passes. The selected cold replay,
Lean and unrelated historical sweeps were not rerun for this verifier-only change.

Open next question: separately reconcile historical witness provenance with live
tooling, retaining explicit equivalence evidence and immutable original pins.

## Scope and credit

Douglas R. Colkitt authored the shared-point and exclusion circuits; icekylinx
adapted the partial-swap producer; Wentao Li (VictorLiwentao) contributed the
PR2039 optimizations. The h25 producer credits the PR36/PR21 base-two graph,
PR32 structured profiler and Zhihao Chen's PR29 label audit. All existing license
and attribution notices are preserved. SovereignSteak prepared this repair with
OpenAI Codex assistance.

No asymptotic construction, conditional hypothesis or selected record changes.
Finite verification here does not prove the full conditional multiplication theorem.
2 changes: 1 addition & 1 deletion research/partial-swap-digest/verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
BASE_COMMIT = "0b1cccf86e2f5132ed286a26ef0a681a495740ea"
ORIGINAL_BLOB = "a2f0190704db83bd8ef48e46e723c49b925804fe"
ORIGINAL_SHA256 = "81e9af92cdf38243a540cdcff2062778e449467848d444da37a9553c12ca4c34"
OPTIMIZED_SHA256 = "7290bd639600aecff11941d3faf95c9ce95589125cc6a7f7440fb86af7a0f17c"
OPTIMIZED_SHA256 = "5a0646a50b9f3e8ea55168620a78e8853b0ab810517cefc8cfb8696aedee278a"
BASE_CERT_SHA256 = "f3c4be597b2f2136da4ae2cc80c7454f63c90aa01f84e5b8131cee4dd55de815"
CERT_REL = "certificates/partial-swap-network.json"
SOURCE_REL = "scripts/partial_swap/shared.py"
Expand Down
2 changes: 1 addition & 1 deletion research/partial-swap-init/verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
BASE_COMMIT = "3b29a00f972bd15871baac0acf5ac204740a9863"
ORIGINAL_BLOB = "77a3672dce3b377eee30a6c3e993a63c2d3840d5"
ORIGINAL_SHA256 = "b27c8bfe1de3f7d2d5fb19ac742adf11597c2aaa7add68430443119997e646e8"
OPTIMIZED_SHA256 = "7290bd639600aecff11941d3faf95c9ce95589125cc6a7f7440fb86af7a0f17c"
OPTIMIZED_SHA256 = "5a0646a50b9f3e8ea55168620a78e8853b0ab810517cefc8cfb8696aedee278a"
BASE_CERT_SHA256 = "6e6ebabf06ee125e58f6871748aaa1fddc4cbf5e70338c61742bca85b9b3e7d4"
FULL_SIZE_SHA256 = "b0402f9eaaf138129939521c2a2ef1c3e8230b730de0a7bdea3596eb415dd173"
CERT_REL = "certificates/partial-swap-network.json"
Expand Down
4 changes: 2 additions & 2 deletions scripts/partial_swap/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,10 @@ def verify(self):
for (common,target),node in sorted(self.outputs.items()):
excluded=tuple(sorted(points[common].index(x) for x in target if x!=common))
assert support_in(node,common)==local_support[local_outputs[excluded]]
t0,t1,t2=target
target_text=','.join(map(str,target))
# Byte-identical to json.dumps((common,target,node),
# separators=(',',':'))+'\n'
update(encode(f'[{common},[{t0},{t1},{t2}],{node}]\n'))
update(encode(f'[{common},[{target_text}],{node}]\n'))
return dict(h=self.h,inputs=len(self.inputs),partial_outputs=len(self.outputs),
additions=self.additions,roles=self.additions+len(self.outputs),
merged_additions=self.merged,
Expand Down
27 changes: 26 additions & 1 deletion tests/test_partial_swap_digest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
sys.path.insert(0, str(ROOT / "scripts"))

from partial_swap import shared as production # noqa: E402
from partial_swap.graph import graph # noqa: E402

ORIGINAL_SHA256 = "81e9af92cdf38243a540cdcff2062778e449467848d444da37a9553c12ca4c34"
OPTIMIZED_SHA256 = "7290bd639600aecff11941d3faf95c9ce95589125cc6a7f7440fb86af7a0f17c"
OPTIMIZED_SHA256 = "5a0646a50b9f3e8ea55168620a78e8853b0ab810517cefc8cfb8696aedee278a"


def load_baseline():
Expand Down Expand Up @@ -74,6 +75,30 @@ def test_small_circuit_receipts_match(self):
circuit.verify(),
)

def test_retained_total_receipts_match(self):
# graph() adds an empty-exclusion local output, lifted to (common,).
for h in (6, 8, 10, 25):
with self.subTest(h=h):
circuit = graph(h)
self.assertEqual(sum(len(t) == 1 for _, t in circuit.outputs), h)
receipt = circuit.verify()
self.assertEqual(self.baseline.SharedPointCircuit.verify(circuit), receipt)
if h == 25:
frozen = json.loads((ROOT / "research/copied-fixed-reversed/producer-input-25.json").read_text())
self.assertEqual(receipt, frozen["scalar"])

def test_wrong_retained_total_rejected(self):
circuit = graph(8)
key = next(key for key in circuit.outputs if len(key[1]) == 1)
common = key[0]
# A proper excluded-pair sum cannot replace the full retained total.
circuit.outputs[key] = next(node for (c, t), node in circuit.outputs.items()
if c == common and len(t) == 3)
with self.assertRaises(AssertionError):
circuit.verify()
with self.assertRaises(AssertionError):
self.baseline.SharedPointCircuit.verify(circuit)

def test_support_rejection_preserved(self):
circuit = production.SharedPointCircuit(8)
node = next(n for n in circuit.active if circuit.args[n])
Expand Down
2 changes: 1 addition & 1 deletion tests/test_partial_swap_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

BASE_COMMIT = "3b29a00f972bd15871baac0acf5ac204740a9863"
ORIGINAL_SHA256 = "b27c8bfe1de3f7d2d5fb19ac742adf11597c2aaa7add68430443119997e646e8"
OPTIMIZED_SHA256 = "7290bd639600aecff11941d3faf95c9ce95589125cc6a7f7440fb86af7a0f17c"
OPTIMIZED_SHA256 = "5a0646a50b9f3e8ea55168620a78e8853b0ab810517cefc8cfb8696aedee278a"


def load_baseline():
Expand Down