Skip to content

harness: use a conforming RFC 8785 canonicalizer - #2

Open
laxsharma wants to merge 1 commit into
a2a-settlement:mainfrom
laxsharma:fix/rfc8785-canonicalization
Open

harness: use a conforming RFC 8785 canonicalizer#2
laxsharma wants to merge 1 commit into
a2a-settlement:mainfrom
laxsharma:fix/rfc8785-canonicalization

Conversation

@laxsharma

Copy link
Copy Markdown
Contributor

Use a conforming RFC 8785 canonicalizer in the harness

manifest.json declares "canonicalizer": "rfc8785@0.1.4", and the
verification recipe says the payload is RFC 8785 canonical JSON. The
harness implements that as
json.dumps(sort_keys=True, separators=(",", ":")), which is not RFC 8785
and which its own docstring described as a "JCS subset".

The two agree byte-for-byte on all five current v0 vectors, so nothing is
broken today. That is a property of the vectors, not of the code: they are
pure ASCII and carry amount as a string rather than a JSON number. The
first vector that is neither will be signed correctly by a conforming
signer and then rejected here, and it will surface as
payload bytes != canonical unsigned vector, which reads like a forged
signature rather than a canonicalizer mismatch.

Divergences, all verified against rfc8785 0.1.4:

input json.dumps RFC 8785
{"note":"café"} {"note":"café"} {"note":"café"}
{"merchant":"München GmbH"} escaped UTF-8
{"amount":1e16} 1e+16 10000000000000000
{"amount":-0.0} -0.0 0
{"😀":1,"�":2} U+FFFD first 😀 first (UTF-16 order)

Changes:

  • harness/jws.py uses rfc8785.dumps.
  • rfc8785>=0.1.4 added to harness/requirements.txt.
  • tests/test_canonicalization.py covers the string, number and
    sort-order cases. Every case fails before this change and passes after.
  • One regression test asserts the five vendored vectors canonicalize
    identically under both implementations, so the change is
    signature-preserving for everything currently in the corpus.
  • docs/vector-format.md step 2 no longer describes the approximation as
    the recipe.

Verified locally: python -m harness.validate_vectors --vectors vectors/v0
reports all 5 valid, and pytest tests/ is 20 passed.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com

`manifest.json` declares `"canonicalizer": "rfc8785@0.1.4"`, and the
verification recipe says the payload is RFC 8785 canonical JSON. The
harness implements that as
`json.dumps(sort_keys=True, separators=(",", ":"))`, which is not RFC 8785
and which its own docstring described as a "JCS subset".

The two agree byte-for-byte on all five current v0 vectors, so nothing is
broken today. That is a property of the vectors, not of the code: they are
pure ASCII and carry `amount` as a string rather than a JSON number. The
first vector that is neither will be signed correctly by a conforming
signer and then rejected here, and it will surface as
`payload bytes != canonical unsigned vector`, which reads like a forged
signature rather than a canonicalizer mismatch.

Divergences, all verified against `rfc8785` 0.1.4:

| input | `json.dumps` | RFC 8785 |
|---|---|---|
| `{"note":"café"}` | `{"note":"café"}` | `{"note":"café"}` |
| `{"merchant":"München GmbH"}` | escaped | UTF-8 |
| `{"amount":1e16}` | `1e+16` | `10000000000000000` |
| `{"amount":-0.0}` | `-0.0` | `0` |
| `{"😀":1,"�":2}` | U+FFFD first | 😀 first (UTF-16 order) |

Changes:

- `harness/jws.py` uses `rfc8785.dumps`.
- `rfc8785>=0.1.4` added to `harness/requirements.txt`.
- `tests/test_canonicalization.py` covers the string, number and
  sort-order cases. Every case fails before this change and passes after.
- One regression test asserts the five vendored vectors canonicalize
  identically under both implementations, so the change is
  signature-preserving for everything currently in the corpus.
- `docs/vector-format.md` step 2 no longer describes the approximation as
  the recipe.

Verified locally: `python -m harness.validate_vectors --vectors vectors/v0`
reports all 5 valid, and `pytest tests/` is 20 passed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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