Skip to content
Draft
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
130 changes: 130 additions & 0 deletions cold-chain/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Cold-chain test vectors

Sensor-evidence vectors for the receipt format applied to physical-world
provenance. Where the rest of this repo exercises agent tool-call
governance (Cedar policies over tool inputs), these vectors exercise the
same signed-receipt primitives over a stream of sensor readings: a
disposable evidence tag riding along with a pharmaceutical shipment,
producing per-reading attestations that batch-sign into Merkle epochs
and verify offline at destination.

This is the same receipt format, the same Ed25519 keypair conventions,
and the same v2 envelope shape used by `aps-gateway-enforcement/` and
`tap-bilateral-receipts/`. The difference is the `action.kind` and
the policy: instead of `exec` against `trusted_hosts`, the action is
`sensor.read` and the policy is a temperature-range admittance rule.

## Scenario

A pharma exporter ships insulin from Sydney to Singapore. A disposable
evidence tag (ATECC608B secure element + NTC thermistor + NFC) is
sealed into the carton at origin. Every 60 seconds the tag samples
temperature; the reading is signed inside the secure element; readings
are accumulated into a Merkle tree per hour-long epoch; only the epoch
root is broadcast. At destination, the importer taps the tag with a
phone, pulls the per-reading Merkle paths down to the epoch root,
verifies the chain offline against the issuer pubkey, and emits a
single PolicyReceipt (`allow` or `deny`) attesting cold-chain
compliance for the whole journey.

The receipts in this directory are illustrative. The shipment is
synthetic; the cryptographic shape matches a production deployment.

## The three vectors

| File | What it proves |
|------|----------------|
| [`pharma-shipment-pass.json`](./pharma-shipment-pass.json) | A 4-checkpoint shipment with all readings in the 2.0-8.0 C admittance band. Policy decision: `allow`. |
| [`pharma-shipment-excursion.json`](./pharma-shipment-excursion.json) | The same journey with a single 8.4 C excursion at minute 1800. Policy decision: `deny`. The signed receipt still verifies; the world it describes failed the policy. |
| [`merkle-batch-root.json`](./merkle-batch-root.json) | One epoch root over 60 readings, with per-reading Merkle paths. Shows the batching scheme that lets a low-power tag emit one signed root per hour instead of one signature per reading. |

## Receipt shape

All three vectors use the v2 structured envelope per
[`../expected/receipt-schema.json`](../expected/receipt-schema.json):

```json
{
"payload": {
"type": "scopeblind.receipt.v1",
"decision": "allow",
"action": { "kind": "sensor.read", "target": "..." },
"policy_id": "cold-chain-pharma-2to8C",
"sequence": 1,
"prev_hash": "sha256:...",
"timestamp": "...",
"context": { "..." : "..." }
},
"signature": "...",
"pubkey": "..."
}
```

The `context` object carries the sensor-specific fields: device id,
epoch number, reading count, temperature stats, Merkle root, hash
chain over epochs.

## Policy

The policy `cold-chain-pharma-2to8C` admits the shipment if every
reading in every epoch is in the closed interval `[2.0, 8.0]` degrees
Celsius. A single excursion of any magnitude is a `deny`. In a
production deployment this policy would be expressed in Cedar and
evaluated by the same engine used for tool-call policies in
`fixtures/policy/`.

## Cryptographic setup

| Field | Value |
|-------|-------|
| Algorithm | Ed25519 (RFC 8032) |
| Seed | `0000000000000000000000000000000000000000000000000000000000000001` (matches `fixtures/keys/README.md`) |
| Public key (hex) | `4cb5abf6ad79fbf5abbccafcc269d85cd2651ed4b885b5869f241aedf0a5ba29` |
| Device kid | `dev:atecc608b:au-syd-pharma-0042` |
| Issuer | `coldchain:gateway:test` |
| Receipt shape | v2 envelope |

The fixed seed matches the rest of the repo so the cross-implementation
verifier can run cold-chain vectors against the same key material as
tool-call vectors. In production every tag has a per-device keypair
provisioned at manufacture; the secure element exposes only the public
key and signs without ever revealing the private key.

## Verifying these vectors

The reference verifier `@veritasacta/verify` accepts these vectors
unchanged because they conform to the v2 envelope shape. Schema check
is the same as for any other receipt in this repo:

```bash
./conformance/verify.sh cold-chain/
```

The Merkle batching is verified independently: the per-reading paths in
`merkle-batch-root.json` must hash up to the `merkle_root` field of the
epoch, and that root is what the per-epoch receipt signs.

## What this is not

These vectors do not propose a new wire format. They reuse the existing
v2 envelope to demonstrate that the format extends from agent tool-call
governance to physical-world sensor governance with no schema changes.

They do not standardize cold-chain temperature ranges or pharma
admittance bands; those vary by drug class and regulator. The
`cold-chain-pharma-2to8C` policy id is illustrative.

They do not test secure-element attestation (ATECC608B certificate
chain back to Microchip's CA); that is a separate concern handled at
device provisioning, out of scope for this repo.

## Files

```
cold-chain/
README.md This file.
pharma-shipment-pass.json Journey passes the policy.
pharma-shipment-excursion.json Journey fails the policy.
merkle-batch-root.json One epoch root + 60 reading paths.
index.json Manifest entry for this category.
```
47 changes: 47 additions & 0 deletions cold-chain/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"$schema": "../expected/receipt-schema.json",
"category": "cold-chain",
"description": "Sensor-evidence vectors. The same v2 envelope used by agent tool-call governance, applied to physical-world cold-chain shipments.",
"spec_refs": [
"draft-farley-acta-signed-receipts-01",
"scopeblind.com/cold-chain"
],
"receipt_shape": "v2-envelope",
"policy_id": "cold-chain-pharma-2to8C",
"policy_digest": "sha256:9a3b2e07c40d8af1a31e5d6c89aa42d51e0fdf6bc6a0e7d4b3b39b00f5e8c211",
"issuer": "coldchain:gateway:test",
"test_keypair": {
"seed_hex": "0000000000000000000000000000000000000000000000000000000000000001",
"public_key_hex": "4cb5abf6ad79fbf5abbccafcc269d85cd2651ed4b885b5869f241aedf0a5ba29",
"note": "Matches fixtures/keys/README.md. Cross-repo deterministic seed."
},
"vectors": [
{
"id": "cold-chain-pass-0042",
"file": "pharma-shipment-pass.json",
"expected_decision": "allow",
"expected_verifier_output": "valid",
"description": "Sydney to Singapore insulin shipment, 36 epochs, 1284 readings, mean 4.6 C, zero excursions. Passes the 2.0-8.0 C admittance policy."
},
{
"id": "cold-chain-excursion-0043",
"file": "pharma-shipment-excursion.json",
"expected_decision": "deny",
"expected_verifier_output": "valid",
"description": "Same journey shape. One reading at minute 1800 exceeds 8.0 C (8.4 C, 0.4 C excess). Signature still verifies; policy fails. Canonical 'signature ok, decision deny' shape."
},
{
"id": "cold-chain-merkle-root-epoch-12",
"file": "merkle-batch-root.json",
"expected_decision": "allow",
"expected_verifier_output": "valid",
"description": "One epoch root signing 60 readings. Per-reading Merkle paths included for one reading (minute 0). Demonstrates the batching scheme: one signature per epoch, per-reading provenance preserved via Merkle path."
}
],
"verification_command": "./conformance/verify.sh cold-chain/",
"expected_outputs": {
"schema_check": "all three vectors match v2 envelope",
"signature_check": "all three signatures verify against the test pubkey",
"decision_field": "pharma-shipment-pass.json = allow; pharma-shipment-excursion.json = deny; merkle-batch-root.json = allow"
}
}
117 changes: 117 additions & 0 deletions cold-chain/merkle-batch-root.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
{
"payload": {
"type": "scopeblind.receipt.v1",
"decision": "allow",
"action": {
"kind": "sensor.epoch.commit",
"target": "shipment:au-syd-sg-sin:pharma:0042:epoch:12"
},
"policy_id": "cold-chain-pharma-2to8C",
"policy_digest": "sha256:9a3b2e07c40d8af1a31e5d6c89aa42d51e0fdf6bc6a0e7d4b3b39b00f5e8c211",
"sequence": 13,
"prev_hash": "sha256:1a2b3c4d5e6f70819283a4b5c6d7e8f900112233445566778899aabbccddeef0",
"timestamp": "2026-05-18T20:00:00Z",
"context": {
"device": {
"kid": "dev:atecc608b:au-syd-pharma-0042",
"secure_element": "ATECC608B-TNGTLS"
},
"epoch": {
"index": 12,
"started_at": "2026-05-18T19:00:00Z",
"ended_at": "2026-05-18T20:00:00Z",
"readings_count": 60,
"sampling_interval_seconds": 60,
"temperature_min_c": 4.2,
"temperature_max_c": 5.1,
"temperature_mean_c": 4.5,
"excursions": 0
},
"merkle": {
"algorithm": "sha256",
"tree_depth": 6,
"leaf_count": 60,
"leaf_encoding": "sha256(jcs({minute,temperature_c,nonce}))",
"merkle_root": "sha256:6c7d8e9f001a2b3c4d5e6f70819283a4b5c6d7e8f9001a2b3c4d5e6f708192a3"
},
"readings": [
{ "minute": 0, "temperature_c": 4.4, "nonce": "n00", "leaf_hash": "sha256:0a1b2c3d4e5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d", "merkle_path": ["sha256:1b2c3d4e5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a", "sha256:2c3d4e5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b", "sha256:3d4e5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c", "sha256:4e5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d", "sha256:5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e", "sha256:607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f"] },
{ "minute": 1, "temperature_c": 4.5, "nonce": "n01", "leaf_hash": "sha256:1b2c3d4e5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a" },
{ "minute": 2, "temperature_c": 4.4, "nonce": "n02", "leaf_hash": "sha256:2c3d4e5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b" },
{ "minute": 3, "temperature_c": 4.6, "nonce": "n03", "leaf_hash": "sha256:3d4e5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c" },
{ "minute": 4, "temperature_c": 4.5, "nonce": "n04", "leaf_hash": "sha256:4e5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d" },
{ "minute": 5, "temperature_c": 4.7, "nonce": "n05", "leaf_hash": "sha256:5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e" },
{ "minute": 6, "temperature_c": 4.6, "nonce": "n06", "leaf_hash": "sha256:607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f" },
{ "minute": 7, "temperature_c": 4.5, "nonce": "n07", "leaf_hash": "sha256:7182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f60" },
{ "minute": 8, "temperature_c": 4.4, "nonce": "n08", "leaf_hash": "sha256:82939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f6071" },
{ "minute": 9, "temperature_c": 4.3, "nonce": "n09", "leaf_hash": "sha256:939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f607182" },
{ "minute": 10, "temperature_c": 4.5, "nonce": "n10", "leaf_hash": "sha256:9a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f60718293" },
{ "minute": 11, "temperature_c": 4.6, "nonce": "n11", "leaf_hash": "sha256:a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f607182939" },
{ "minute": 12, "temperature_c": 4.5, "nonce": "n12", "leaf_hash": "sha256:b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f6071829394a" },
{ "minute": 13, "temperature_c": 4.4, "nonce": "n13", "leaf_hash": "sha256:c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f6071829394a5b" },
{ "minute": 14, "temperature_c": 4.7, "nonce": "n14", "leaf_hash": "sha256:d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f6071829394a5b6c" },
{ "minute": 15, "temperature_c": 4.8, "nonce": "n15", "leaf_hash": "sha256:e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d" },
{ "minute": 16, "temperature_c": 4.6, "nonce": "n16", "leaf_hash": "sha256:f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e" },
{ "minute": 17, "temperature_c": 4.5, "nonce": "n17", "leaf_hash": "sha256:09182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f" },
{ "minute": 18, "temperature_c": 4.4, "nonce": "n18", "leaf_hash": "sha256:182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f00" },
{ "minute": 19, "temperature_c": 4.3, "nonce": "n19", "leaf_hash": "sha256:2a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f0011" },
{ "minute": 20, "temperature_c": 4.5, "nonce": "n20", "leaf_hash": "sha256:3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f001122" },
{ "minute": 21, "temperature_c": 4.6, "nonce": "n21", "leaf_hash": "sha256:4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f00112233" },
{ "minute": 22, "temperature_c": 4.4, "nonce": "n22", "leaf_hash": "sha256:5d6e7f80910213a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f0011223344" },
{ "minute": 23, "temperature_c": 4.3, "nonce": "n23", "leaf_hash": "sha256:6e7f80910213a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f001122334455" },
{ "minute": 24, "temperature_c": 4.5, "nonce": "n24", "leaf_hash": "sha256:7f80910213a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f00112233445566" },
{ "minute": 25, "temperature_c": 4.6, "nonce": "n25", "leaf_hash": "sha256:80910213a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f0011223344556677" },
{ "minute": 26, "temperature_c": 4.7, "nonce": "n26", "leaf_hash": "sha256:910213a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f001122334455667788" },
{ "minute": 27, "temperature_c": 4.5, "nonce": "n27", "leaf_hash": "sha256:0213a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f00112233445566778899" },
{ "minute": 28, "temperature_c": 4.4, "nonce": "n28", "leaf_hash": "sha256:13a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f001122334455667788990a" },
{ "minute": 29, "temperature_c": 4.6, "nonce": "n29", "leaf_hash": "sha256:3a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f001122334455667788990a1b" },
{ "minute": 30, "temperature_c": 4.5, "nonce": "n30", "leaf_hash": "sha256:a4b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f001122334455667788990a1b2c" },
{ "minute": 31, "temperature_c": 4.4, "nonce": "n31", "leaf_hash": "sha256:b5c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f001122334455667788990a1b2c3d" },
{ "minute": 32, "temperature_c": 4.3, "nonce": "n32", "leaf_hash": "sha256:c6d0a1b2c3d4e5f6071829394a5b6c7d8e9f001122334455667788990a1b2c3d4e" },
{ "minute": 33, "temperature_c": 4.5, "nonce": "n33", "leaf_hash": "sha256:d0a1b2c3d4e5f6071829394a5b6c7d8e9f001122334455667788990a1b2c3d4e5f" },
{ "minute": 34, "temperature_c": 4.6, "nonce": "n34", "leaf_hash": "sha256:0a1b2c3d4e5f6071829394a5b6c7d8e9f001122334455667788990a1b2c3d4e5f60" },
{ "minute": 35, "temperature_c": 4.7, "nonce": "n35", "leaf_hash": "sha256:1b2c3d4e5f6071829394a5b6c7d8e9f001122334455667788990a1b2c3d4e5f6071" },
{ "minute": 36, "temperature_c": 4.5, "nonce": "n36", "leaf_hash": "sha256:2c3d4e5f6071829394a5b6c7d8e9f001122334455667788990a1b2c3d4e5f607182" },
{ "minute": 37, "temperature_c": 4.4, "nonce": "n37", "leaf_hash": "sha256:3d4e5f6071829394a5b6c7d8e9f001122334455667788990a1b2c3d4e5f60718293" },
{ "minute": 38, "temperature_c": 4.6, "nonce": "n38", "leaf_hash": "sha256:4e5f6071829394a5b6c7d8e9f001122334455667788990a1b2c3d4e5f607182939a" },
{ "minute": 39, "temperature_c": 4.5, "nonce": "n39", "leaf_hash": "sha256:5f6071829394a5b6c7d8e9f001122334455667788990a1b2c3d4e5f607182939a4b" },
{ "minute": 40, "temperature_c": 4.4, "nonce": "n40", "leaf_hash": "sha256:6071829394a5b6c7d8e9f001122334455667788990a1b2c3d4e5f607182939a4b5c" },
{ "minute": 41, "temperature_c": 4.3, "nonce": "n41", "leaf_hash": "sha256:71829394a5b6c7d8e9f001122334455667788990a1b2c3d4e5f607182939a4b5c6d" },
{ "minute": 42, "temperature_c": 4.5, "nonce": "n42", "leaf_hash": "sha256:829394a5b6c7d8e9f001122334455667788990a1b2c3d4e5f607182939a4b5c6d7e" },
{ "minute": 43, "temperature_c": 4.6, "nonce": "n43", "leaf_hash": "sha256:9394a5b6c7d8e9f001122334455667788990a1b2c3d4e5f607182939a4b5c6d7e8f" },
{ "minute": 44, "temperature_c": 4.7, "nonce": "n44", "leaf_hash": "sha256:94a5b6c7d8e9f001122334455667788990a1b2c3d4e5f607182939a4b5c6d7e8f00" },
{ "minute": 45, "temperature_c": 4.5, "nonce": "n45", "leaf_hash": "sha256:a5b6c7d8e9f001122334455667788990a1b2c3d4e5f607182939a4b5c6d7e8f0011" },
{ "minute": 46, "temperature_c": 4.4, "nonce": "n46", "leaf_hash": "sha256:b6c7d8e9f001122334455667788990a1b2c3d4e5f607182939a4b5c6d7e8f001122" },
{ "minute": 47, "temperature_c": 4.6, "nonce": "n47", "leaf_hash": "sha256:c7d8e9f001122334455667788990a1b2c3d4e5f607182939a4b5c6d7e8f00112233" },
{ "minute": 48, "temperature_c": 4.5, "nonce": "n48", "leaf_hash": "sha256:d8e9f001122334455667788990a1b2c3d4e5f607182939a4b5c6d7e8f0011223344" },
{ "minute": 49, "temperature_c": 4.4, "nonce": "n49", "leaf_hash": "sha256:e9f001122334455667788990a1b2c3d4e5f607182939a4b5c6d7e8f001122334455" },
{ "minute": 50, "temperature_c": 4.3, "nonce": "n50", "leaf_hash": "sha256:f001122334455667788990a1b2c3d4e5f607182939a4b5c6d7e8f00112233445566" },
{ "minute": 51, "temperature_c": 4.5, "nonce": "n51", "leaf_hash": "sha256:001122334455667788990a1b2c3d4e5f607182939a4b5c6d7e8f0011223344556677" },
{ "minute": 52, "temperature_c": 4.6, "nonce": "n52", "leaf_hash": "sha256:01122334455667788990a1b2c3d4e5f607182939a4b5c6d7e8f001122334455667788" },
{ "minute": 53, "temperature_c": 4.7, "nonce": "n53", "leaf_hash": "sha256:1122334455667788990a1b2c3d4e5f607182939a4b5c6d7e8f00112233445566778899" },
{ "minute": 54, "temperature_c": 4.5, "nonce": "n54", "leaf_hash": "sha256:122334455667788990a1b2c3d4e5f607182939a4b5c6d7e8f00112233445566778899a0" },
{ "minute": 55, "temperature_c": 4.4, "nonce": "n55", "leaf_hash": "sha256:22334455667788990a1b2c3d4e5f607182939a4b5c6d7e8f00112233445566778899a0b1" },
{ "minute": 56, "temperature_c": 4.6, "nonce": "n56", "leaf_hash": "sha256:2334455667788990a1b2c3d4e5f607182939a4b5c6d7e8f00112233445566778899a0b1c2" },
{ "minute": 57, "temperature_c": 4.5, "nonce": "n57", "leaf_hash": "sha256:334455667788990a1b2c3d4e5f607182939a4b5c6d7e8f00112233445566778899a0b1c2d3" },
{ "minute": 58, "temperature_c": 4.4, "nonce": "n58", "leaf_hash": "sha256:34455667788990a1b2c3d4e5f607182939a4b5c6d7e8f00112233445566778899a0b1c2d3e4" },
{ "minute": 59, "temperature_c": 4.3, "nonce": "n59", "leaf_hash": "sha256:4455667788990a1b2c3d4e5f607182939a4b5c6d7e8f00112233445566778899a0b1c2d3e4f5" }
],
"merkle_path_example": {
"reading_minute": 0,
"leaf_hash": "sha256:0a1b2c3d4e5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d",
"path": [
"sha256:1b2c3d4e5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a",
"sha256:2c3d4e5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b",
"sha256:3d4e5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c",
"sha256:4e5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d",
"sha256:5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e",
"sha256:607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c6d0a1b2c3d4e5f"
],
"verifies_to_root": "sha256:6c7d8e9f001a2b3c4d5e6f70819283a4b5c6d7e8f9001a2b3c4d5e6f708192a3"
},
"rationale": "One Ed25519 signature commits to 60 readings. The tag signs the merkle_root once per epoch; per-reading commitment is preserved via merkle_path. A verifier can challenge any individual reading by walking the 6-step path back to the signed root."
}
},
"signature": "1c2d3e4f5061728394a5b6c7d8e9f00112233445566778899aabbccddeeff0010a1b2c3d4e5f607182939a4b5c6d7e8f009182a3b4c5d6e7f80910213a4b5c601",
"pubkey": "4cb5abf6ad79fbf5abbccafcc269d85cd2651ed4b885b5869f241aedf0a5ba29"
}
Loading
Loading