Skip to content

feat(atecc608-ecdsa-jcs-receipt): reference ATECC608B signed-receipt example#1

Open
tomjwxf wants to merge 1 commit intomainfrom
feat/atecc608-ecdsa-jcs-receipt
Open

feat(atecc608-ecdsa-jcs-receipt): reference ATECC608B signed-receipt example#1
tomjwxf wants to merge 1 commit intomainfrom
feat/atecc608-ecdsa-jcs-receipt

Conversation

@tomjwxf
Copy link
Copy Markdown

@tomjwxf tomjwxf commented Apr 18, 2026

Reference implementation showing the ATECC608B + JCS + ECDSA P-256 flow for draft-farley-acta-signed-receipts-01 receipts.

Decomposition: the secure element is a signing oracle (sign 32-byte digest → 64-byte r||s). Host-side Python handles canonicalization, envelope assembly, and fixture generation. That's the right boundary for production cold-chain firmware; it also keeps on-device surface tiny and independently testable.

Contents

  • src/receipt_signer.{c,h} — thin cryptoauthlib wrapper (init, sign 32-byte digest, read pubkey, release)
  • src/example_main.c — CLI that signs a hex digest from argv
  • host/build_receipt.py — three modes:
    • reference — produces byte-reproducible sample using software ECDSA P-256 with deterministic seed
    • build — given a pubkey, prints canonical envelope + SHA-256 digest to feed the device
    • assemble — given device's signature + pubkey, emits the final receipt JSON
  • sample_receipt.json — pre-generated reference output (verified against cryptography lib)
  • Makefile — Linux host build against installed libcryptoauth

Honest note on chip capability

ATECC608B is ECDSA P-256 only — does not support Ed25519 natively. Ed25519 (the IETF draft's mandatory-to-implement algorithm) needs TA100, NXP SE050, or software signing.

This example takes the honest path: ECDSA today (cheapest secure element, widely stocked, real hardware-bound keys), Ed25519 later either via native-Ed25519 secure elements or via ES256 support in @veritasacta/verify tracked in VeritasActa/verify#4.

If someone wants to follow up with an SE050 or TA100 variant, that's a separate example in this repo with the same receipt shape and same canonicalization, just a different secure-element driver.

Cross-implementation posture

This is the first hardware-signer reference in the ScopeBlind examples catalog. Software implementations conforming to the same receipt format are tracked in ScopeBlind/agent-governance-testvectors (currently protect-mcp, protect-mcp-adk, agent-passport-system, sb-runtime — all exit-0 against reference verifier).

Once the first Seal pilot devices ship, this example becomes the reference for how firmware teams integrate ATECC608B into the signed-receipt pipeline.

Related work (parallel landing)

  • ruuvi/ruuvi.firmware.c#381 — RFC on adding software Ed25519 signed-receipt mode to Ruuvi's BLE tags (different hardware, same receipt format)
  • AGT example at microsoft/agent-governance-toolkit/examples/physical-attestation-governed/ — software-side SINT refusal receipt, companion to this hardware-side example

Tested

  • python3 host/build_receipt.py reference produces a 595-byte canonical envelope with SHA-256 digest 5dfbae0449122458ecb3ff5503cb8d3bd89a3c1c3e99d25871aa8c4f43ea4a6f
  • Signature independently verified against cryptography.hazmat ECDSA P-256 verify
  • C code compiled-checked against cryptoauthlib main branch (2026-04); real-hardware verification pending first ATECC608B pilot device arrival

Minimal reference implementation showing the ATECC608B + JCS + ECDSA
P-256 flow for draft-farley-acta-signed-receipts-01 receipts.

Decomposition: the secure element is a signing oracle (sign 32-byte
digest -> 64-byte r||s). Host-side Python handles canonicalization,
envelope assembly, and sample fixture generation. That's the right
boundary for production cold-chain firmware; it also keeps the
on-device surface tiny and independently testable.

- src/receipt_signer.{c,h}: thin cryptoauthlib wrapper
- src/example_main.c: CLI that signs a hex digest from argv
- host/build_receipt.py: canonicalizer, envelope builder, reference
  fixture generator (produces byte-reproducible output via a
  deterministic seed)
- sample_receipt.json: pre-generated reference receipt
- Makefile: Linux host build against installed libcryptoauth

ATECC608B is ECDSA P-256 only -- does not support Ed25519 natively.
Ed25519 requires TA100 or SE050. This example takes the honest path:
ECDSA today (cheapest secure element, widely stocked), Ed25519 later
once native-Ed25519 secure elements are in the Seal BOM or once
VeritasActa/verify#4 adds ES256 support (making ECDSA receipts
first-class verifiable via the standard verifier).

Offered for upstream consideration to MicrochipTech/cryptoauthlib.
@tomjwxf
Copy link
Copy Markdown
Author

tomjwxf commented Apr 18, 2026

CryptoAuthLib upstream conversation opened: MicrochipTech/cryptoauthlib#415. If they accept, C portions would upstream under Microchip's contribution terms; Python host companion stays in this repo under MIT and the cryptoauthlib example links back.

tomjwxf pushed a commit that referenced this pull request Apr 19, 2026
…xample

Companion to the ATECC608B example (PR #1). SE050 supports Ed25519
natively in hardware, which is the IETF draft's mandatory-to-implement
algorithm. Receipts emitted from this signer verify directly against
@veritasacta/verify without needing ES256 adapter support.

Same host/device decomposition as the ATECC608B example:
- Device signs pre-hashed 32-byte digests, nothing else
- Host (Python) handles JCS canonicalization + envelope assembly
- 64-byte Ed25519 R||S signature crosses I2C

Files:
- src/receipt_signer.{c,h}: thin nxp-plugandtrust wrapper
  (init, sign 32-byte digest via sss_asymmetric_sign_digest, read pubkey)
- src/example_main.c: CLI that signs a hex digest from argv
- host/build_receipt.py: canonicalizer + reference fixture generator
  (deterministic seed -> byte-reproducible sample_receipt.json)
- sample_receipt.json: 598-byte canonical envelope, signature
  cross-verified against cryptography.hazmat Ed25519 verify
- Makefile: Linux host build against installed nxp-plugandtrust

Decision when to use SE050 vs ATECC608B:
- Ed25519 native required (IETF spec conformance, pharma, regulatory) -> SE050
- Cost dominates at volume, ECDSA P-256 + ES256 adapter acceptable -> ATECC608B
- Documented tradeoff table in README.

Tested:
- host/build_receipt.py reference produces reproducible 598-byte envelope
- SHA-256 digest: 8310e6166a5851c8f0ab21739a4fdf32d6f94180cad891d53770c9b692a469d1
- Signature independently verified via cryptography.hazmat Ed25519
- C code compiled-checked against nxp-plugandtrust SSS API surface;
  real-hardware verification pending first SE050 dev-board acquisition
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.

2 participants