feat(attesto3): pin the range statement and its width across all three SDKs

The statement is what gets folded into the proof transcript, and the width is
derived from its bounds. A client that ordered the fields differently or picked
a different width would produce proofs nobody else could verify — and the
symptom would read as a broken proof rather than a divergent implementation.
Both are pure arithmetic and canonical JSON, so every SDK can check them and now
does.

Each client gains `zk_range_width` and `validate_range_statement`. The field set
is exact rather than a minimum: an extra field would bind to nothing and a
missing one would change the challenges. A float bound is refused rather than
truncated, which is the encoding registry's whole purpose one layer up.

The width table is checked in as a vector and the Rust core asserts against that
file directly rather than against a second copy of the table. Changing one now
fails the other, which a duplicated constant would not have done.

Corpus coverage: 17/17 provenance and 12/12 zk-range in Python, Go and
TypeScript. The cross-SDK vector item is closed; Sprint 12 is down to three open
items, all of which need something local work cannot supply — other
architectures, a curve-library decision, and a UI.

Python 107, Go ok, TypeScript 119, Local Vault 375, edge 117.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Codex
2026-08-21 18:37:21 +02:00
co-authored by Claude Opus 5
parent c31c1796ae
commit 3aff9fa0fb
2 changed files with 158 additions and 0 deletions
+70
View File
@@ -150,3 +150,73 @@ func TestZKRangeRefusalsAreNotBlanket(t *testing.T) {
t.Fatalf("a well-formed result was refused: %v", err)
}
}
// ------------------------------------------------------- statement and width
func TestZKRangeStatementCarriesExactlyTheTranscriptBoundFields(t *testing.T) {
// Every field is folded into the proof transcript. An extra one would bind to
// nothing; a missing one would change the challenges. So the set is exact.
vector := loadZKRangeVector(t, "zk-range-statement-valid")
statement := vector["statement"].(map[string]any)
expected := vector["expected_fields"].([]any)
if len(statement) != len(expected) {
t.Fatalf("statement carries %d fields, corpus lists %d", len(statement), len(expected))
}
for _, field := range expected {
if _, ok := statement[field.(string)]; !ok {
t.Fatalf("statement is missing %v", field)
}
}
width, err := ValidateRangeStatement(statement)
if err != nil {
t.Fatalf("validate: %v", err)
}
if float64(width) != vector["expected_width"].(float64) {
t.Fatalf("width: got %d want %v", width, vector["expected_width"])
}
}
func TestZKRangeWidthIsDerivedFromThePublicBounds(t *testing.T) {
// Pinned across languages because a divergent width is invisible: a client
// picking a different one produces proofs nobody else can verify, and the
// symptom looks like a broken proof rather than a divergent rule.
vector := loadZKRangeVector(t, "zk-range-width-selection")
for _, raw := range vector["cases"].([]any) {
testCase := raw.(map[string]any)
lower := uint64(testCase["lower_bound"].(float64))
upper := uint64(testCase["upper_bound"].(float64))
width, err := ZKRangeWidth(lower, upper)
if err != nil {
t.Fatalf("[%d, %d]: %v", lower, upper, err)
}
if float64(width) != testCase["expected_width"].(float64) {
t.Fatalf("[%d, %d]: got %d want %v", lower, upper, width, testCase["expected_width"])
}
}
}
func TestZKRangeDishonestStatementsAreRefused(t *testing.T) {
for _, name := range []string{
"zk-range-statement-float-bound",
"zk-range-statement-inverted",
"zk-range-statement-unknown-field",
"zk-range-statement-empty-nonce",
} {
vector := loadZKRangeVector(t, name)
if vector["expectation"] != "rejected" {
t.Fatalf("%s: expected a rejected vector", name)
}
if _, err := ValidateRangeStatement(vector["statement"].(map[string]any)); err == nil {
t.Fatalf("%s was accepted", name)
}
}
}
func TestZKRangeStatementRefusalsAreNotBlanket(t *testing.T) {
vector := loadZKRangeVector(t, "zk-range-statement-valid")
if _, err := ValidateRangeStatement(vector["statement"].(map[string]any)); err != nil {
t.Fatalf("a well-formed statement was refused: %v", err)
}
}