2. Secure Ingestion & Transmission
Summary: Proof starts before the chain. EDMA only admits data that arrives over authenticated, encrypted channels, is signed at the source, is canonicalized to a stable JSON, and includes strong replay protection. Anything else is rejected upstream—long before PoV attestations.
Threat model
Tampering in transit (MITM, header/body swap)
Spoofed devices (fake meter identity, cloned keys)
Replay (old windows resent to mint again)
Ambiguity (pretty-printed JSON, unit drift, clock drift)
Flooding (DoS via duplicate or overlapping windows)
Transport & authentication
Encryption: mTLS/TLS 1.2+ for HTTPS or MQTTs; TLS cipher suites with PFS
Mutual auth: device/client certs or OAuth2 client-credentials; rotate keys; short-lived tokens
Scopes: per-device permissions (write only its own device_id); no wildcard writes
Headers: include X-Device-Id, X-Window-Id (batch_id), X-Nonce, X-Signature, X-Timestamp (ms)
Source signing
On-device signatures: sign the canonical JSON or its SHA-256 with a key in a secure element/HSM
Signature format: Ed25519 or ECDSA P-256; send as Base64 in X-Signature
Key registry: commissioning binds public key → device_id; compromised keys are revoked
Canonicalization boundary
Rule: devices (or gateways) must submit canonical JSON (sorted keys, minified, fixed units/types)
Digest: evidenceHash = SHA-256(utf8(canonical_json))
Equality guarantee: the same reality always hashes to the same bytes; PoV equality checks rely on this
Minimal payload (energy window)
Replay protection & idempotency
Nonces: 32-byte random per window; reject nonce reuse for the same device_id
Window id: batch_id unique per device; server enforces idempotent upsert on batch_id
Timestamp: X-Timestamp (ms) must be within policy skew; stale requests are rejected
Ordering & windows
No overlaps: windows for a device_id must not overlap; server rejects and logs
UTC seconds: start_ts and end_ts are UTC; include clock_offset_ms when available
Units: report quantity_wh, not kWh; conversions cause equality failures
Edge buffering & retry
Store-and-forward: buffer when offline; resend original canonical JSON + headers
Backoff: exponential retry with jitter; cap max attempts; do not mutate payload on retry
Integrity: include source_file_hash when submitting file-based exports
Ingestion API contract (HTTP example)
Endpoint: POST /v1/ingest/meter-window
Headers (required):
Content-Type: application/json
X-Device-Id: 0x…32
X-Window-Id: 0x…32 (batch_id)
X-Nonce: 0x…32
X-Timestamp: 1700000000000 (ms)
X-Signature: base64(ed25519_sign(canonical_json))
Body: canonical JSON (see minimal payload)
Server checks: mTLS → header auth → signature verify → duplicate/overlap → canonicalization → enqueue for attestation
From ingestion to PoV
Ingest canonical JSON over mTLS with signature
Verify signature, nonces, window rules, and dedupe
Compute evidenceHash; persist canonical JSON and meta (off-chain)
Attest MeterReadingBatch.v1 (EAS) with the evidenceHash
Notify authorized attestors; collect Verification.v1 records (must include AUDITOR)
Gate is called by asset/settlement contracts; on pass, mint proofs (gas-only) or settle (EDM)
Minimal examples
TypeScript: canonical hash and header signature
cURL: submit a window
Monitoring & alerts
Auth errors per device (spikes signal key misuse)
Overlap/duplicate rate by device and operator
Signature failures and stale timestamps
End-to-end latency: window close → PoVPassed
Revocation flags impacting recent windows
Conformance checklist
Commission device identity (key → device_id); keep certs rotated
Sign canonical JSON (or its digest) on device/gateway
Encrypt transport (mTLS/TLS) with per-device auth
Prevent replay (nonce + unique batch_id + timestamp skew limits)
Enforce windows (UTC, no overlaps, fixed units)
Persist canonical JSON off-chain; compute and store evidenceHash
Attest MeterReadingBatch.v1; collect Verification.v1 (incl. AUDITOR)
Call PoV Gate in the same transaction that mints/settles
Last updated
