The public history carried kat/__pycache__/mlkem768_reference.cpython-314.pyc, a compiled Python artifact embedding the operator's absolute local path. Text secret scanners do not read compiled binaries, which is exactly how it slipped through, and removing it from the tip would have left it reachable through the old root commits. So this repository is republished from a single clean root. This root also carries, from the previously unpublished line of work: - corrected LICENSE year, LICENSING.md, VERIFY-POLICY.md, and CITATIONS-UNRESOLVED.md remeasured 2026-08-11 (101 paths, README aligned) - O-018: run_consensus_verification.py ran 19 of 29 models and reported PASS; it now runs all 29, and computemarket_smt.py gains resolveByTimeout / reclaimUnsettled cases plus a negative control - O-006: the word 'audited' removed from next to Bouncy Castle, twice, after a concurrent edit resurrected it - O-014: prior art named and dated - Algorand's native falcon_verify shipped about ten months before AERE's precompiles; the primacy claim is withdrawn where it was implied - bench/ scripts parametrized so they actually run for an outsider (the earlier textual sanitization left $STAGING unexpanded inside Python strings) - AIP-2/AIP-3 errata with measured figures, spec remeasurements at 2026-08-01, and the spec-zk-stack retractions (owner is an operational key, not the Foundation; 'maximally sound' withdrawn; aggregator V1 deprecated) The redacted bench-host environment files from the sanitized line are kept exactly as published; the unredacted local variants are not carried.
123 lines
7.8 KiB
Python
123 lines
7.8 KiB
Python
#!/usr/bin/env python3
|
|
# Conformance + cross-language harness for the Fiat-Shamir DUPLEX CHALLENGER (component (f)) of the PQ
|
|
# STARK-verify precompile 0x0AE8. It:
|
|
# 1. runs the Python challenger conformance KAT against the real ground truth emitted by the pinned
|
|
# p3-challenger / p3-fri 0.4.3-succinct crates (challenger-extractor -> challenger_ground_truth.json);
|
|
# 2. asserts Python, Node, and standalone Java produce byte-identical shared vectors (three
|
|
# independent implementations of observe / sample / sample_bits / check_witness);
|
|
# 3. closes the loop END TO END: derive the FRI betas + query indices FROM THE TRANSCRIPT, then feed
|
|
# them into the CONFIRMED FRI verify_query (component (d), fri_verify_reference) and confirm it
|
|
# ACCEPTS the real FRI ground-truth proof and REJECTS a tampered derived beta. This is
|
|
# transcript -> betas/indices -> FRI verify, the loop the FRI KAT left open.
|
|
#
|
|
# It writes ../results/kat-results-challenger.json. The top-level 0x0AE8 stays FAIL-CLOSED regardless
|
|
# (component (e), the AIR, is un-ported); this harness confirms component (f) only.
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
RESULTS = os.path.join(HERE, "..", "results", "kat-results-challenger.json")
|
|
sys.path.insert(0, HERE)
|
|
|
|
import challenger_reference as C
|
|
import fri_verify_reference as FV # component (d), CONFIRMED
|
|
|
|
passed = 0
|
|
failed = 0
|
|
notes = []
|
|
|
|
|
|
def check(name, cond):
|
|
global passed, failed
|
|
if cond:
|
|
passed += 1
|
|
else:
|
|
failed += 1
|
|
notes.append("FAIL: " + name)
|
|
print(("PASS " if cond else "FAIL ") + name)
|
|
|
|
|
|
# ---- 1) Python conformance KAT ----
|
|
p, t, det = C.conformance_kats()
|
|
for d in det:
|
|
check("py." + d["check"], d["pass"])
|
|
|
|
# ---- 2) cross-language byte-identity ----
|
|
py = C.shared_vectors()
|
|
node = json.loads(subprocess.check_output(["node", os.path.join(HERE, "challenger_reference.mjs")]))
|
|
java_out = subprocess.check_output(
|
|
["java", "-cp", os.path.join(HERE, "out"), "ChallengerSelfTest", "--emit",
|
|
os.path.join(HERE, "challenger_ground_truth.json")],
|
|
cwd=HERE)
|
|
java = json.loads(java_out)
|
|
|
|
|
|
def norm(v):
|
|
return json.loads(json.dumps(v))
|
|
|
|
|
|
check("xlang.permZeros.py==node", norm(py["permZeros"]) == norm(node["permZeros"]))
|
|
check("xlang.permZeros.py==java", norm(py["permZeros"]) == norm(java["permZeros"]))
|
|
check("xlang.duplex.py==node", norm(py["duplex"]) == norm(node["duplex"]))
|
|
check("xlang.duplex.py==java", norm(py["duplex"]) == norm(java["duplex"]))
|
|
check("xlang.fri.py==node", norm(py["fri"]) == norm(node["fri"]))
|
|
check("xlang.fri.py==java", norm(py["fri"]) == norm(java["fri"]))
|
|
|
|
# ---- 3) end-to-end loop closure: transcript -> betas/indices -> CONFIRMED FRI verify_query ----
|
|
with open(os.path.join(HERE, "challenger_ground_truth.json")) as fp:
|
|
ch_gt = json.load(fp)
|
|
with open(os.path.join(HERE, "fri_ground_truth.json")) as fp:
|
|
fri_gt = json.load(fp)
|
|
fri_by_name = {c["name"]: c for c in fri_gt["cases"]}
|
|
|
|
for tc in ch_gt["fri_transcript"]:
|
|
name = tc["name"]
|
|
betas, indices, pow_accept = C.derive_fri_challenges(
|
|
tc["commit_phase_commits"], tc["final_poly"], tc["pow_witness"],
|
|
tc["pow_bits"], tc["log_blowup"], tc["num_queries"])
|
|
fc = fri_by_name[name]
|
|
# Build a FRI case that uses the TRANSCRIPT-DERIVED betas (indices already match fc queries).
|
|
check("e2e[%s].derived_indices==fri_gt" % name, indices == [q["index"] for q in fc["queries"]])
|
|
synthetic = {
|
|
"log_blowup": tc["log_blowup"],
|
|
"log_max_height": len(tc["commit_phase_commits"]) + tc["log_blowup"],
|
|
"commit_phase_commits": tc["commit_phase_commits"],
|
|
"final_poly": fc["final_poly"],
|
|
"betas": betas, # <-- derived in-circuit from the transcript
|
|
"num_queries": tc["num_queries"],
|
|
"queries": fc["queries"], # real openings from the confirmed FRI ground truth
|
|
}
|
|
# transcript -> derived betas/indices -> CONFIRMED FRI verify_query must ACCEPT the honest proof.
|
|
check("e2e[%s].fri_verify_accepts_with_derived_betas" % name, FV.verify_case(synthetic) is True)
|
|
# and a tampered derived beta must be REJECTED (soundness of the closed loop).
|
|
check("e2e[%s].fri_verify_rejects_tampered_beta" % name, FV.verify_case(synthetic, "beta") is False)
|
|
|
|
# ---- write results ----
|
|
total = passed + failed
|
|
result = {
|
|
"component": "Fiat-Shamir transcript / Poseidon2 DuplexChallenger (port spec component (f))",
|
|
"precompile": "0x0000000000000000000000000000000000000ae8",
|
|
"scope": "port spec section 7; the duplex-sponge challenger DuplexChallenger<BabyBear, Perm, WIDTH=16, RATE=8> and the GrindingChallenger check_witness: observe (overwrite-mode absorb), sample (squeeze, pop from the end of the rate buffer), sample_bits (low-bits query-index reduction), check_witness (observe witness then sample_bits==0). Wired behind the still-fail-closed top level.",
|
|
"validates": "CONFORMANCE: ground truth emitted by executing the pinned Plonky3 p3-challenger 0.4.3-succinct DuplexChallenger + GrindingChallenger (and the p3-fri verify_shape_and_sample_challenges transcript ORDER). (1) a fully-scripted observe/sample transcript reproduces every sampled base + F_{p^4} ext value, the full 16-lane sponge state, and a check_witness accept/reject table byte-for-byte; (2) the FRI betas + query indices + grinding acceptance are DERIVED from the transcript (commit_phase_commits + final_poly + pow_witness) and match the pinned p3-fri challenger AND the confirmed FRI ground truth; (3) END TO END: those derived betas/indices, fed into the CONFIRMED FRI verify_query (component (d)), accept the real FRI proof and reject a tampered beta. Python/Node/standalone-Java are byte-identical.",
|
|
"does_not_validate": "the SP1 recursion-AIR constraint evaluation (component (e)): the reduced openings, DEEP zeta/alpha challenges, quotient consistency, and vk binding. That is un-ported (StarkConstraints.evaluateAtZeta = UNAVAILABLE). A real exported SP1 v6.1.0 proof's transcript (vkey digest, trace/quotient commitments, opened values order) is still [MEASURE].",
|
|
"top_level_verifier": "unchanged, still FAIL-CLOSED (returns EMPTY for every input). Even with component (f) confirmed and Challenger.spongePorted flipped true, StarkConstraints.evaluateAtZeta returns UNAVAILABLE (component (e) un-ported), so verify() returns UNAVAILABLE before any query loop and computePrecompile returns EMPTY. ACCEPT is unreachable. DO NOT ACTIVATE.",
|
|
"confirmed_config": "DuplexChallenger<BabyBear, Poseidon2<BabyBear,...,16,7>, WIDTH=16, RATE=8>; Witness=BabyBear; Challenge=BinomialExtensionField<BabyBear,4>; sample pops from the END of the rate buffer (Vec::pop); sample_bits masks the LOW `bits` of as_canonical_u64; check_witness = observe(witness) then sample_bits(bits)==0.",
|
|
"pinned_conformance_target": "p3-challenger 0.4.3-succinct (duplex_challenger.rs, grinding_challenger.rs), transcript order p3-fri 0.4.3-succinct verifier.rs (verify_shape_and_sample_challenges), sponge = confirmed Poseidon2-BabyBear (component (b)); byte-identical to the repo Cargo.lock. Extractor: pq-stark/challenger-extractor -> pq-stark/challenger_ground_truth.json.",
|
|
"cross_language": "Python (challenger_reference.py), Node (challenger_reference.mjs), standalone Java (ChallengerSelfTest.java) emit byte-identical shared vectors.",
|
|
"flags": {"Challenger.spongePorted": True, "note": "flipped true: component (f) confirmed. StarkConstraints.evaluateAtZeta stays UNAVAILABLE (component (e)), so the top level stays fail-closed and ACCEPT is unreachable."},
|
|
"notes": notes,
|
|
"passed": passed,
|
|
"failed": failed,
|
|
"total": total,
|
|
}
|
|
os.makedirs(os.path.dirname(RESULTS), exist_ok=True)
|
|
with open(RESULTS, "w") as fp:
|
|
json.dump(result, fp, indent=1)
|
|
|
|
print("\nchallenger conformance: PASS=%d FAIL=%d TOTAL=%d" % (passed, failed, total))
|
|
print("results -> %s" % os.path.normpath(RESULTS))
|
|
sys.exit(0 if failed == 0 else 1)
|