USENAMI / DOCS / ATTESTED DATA

Verify an attested snapshot

Every /v1/perp/attested-snapshot response is signed inside an AWS Nitro Enclave. This page is the complete recipe to check that signature yourself — recompute the digest, recover the signer, and pin the enclave build. No account, and no trust in us, required.

Scope, honestly: the signature proves the payload came from the enclave build named by pcr0 and was not modified afterwards — nothing more. Nothing here is traded or signed on any mainnet, and no funds move. The signing service is pre-audit: the code is public and independently verifiable, but no third-party security audit has been performed yet.

1. What you received

The response is a self-contained bundle:

dataThe snapshot as a raw JSON string — the exact bytes that were signed inside the enclave, served back verbatim. Parse it to read the snapshot; feed it to the verifier untouched.
signature65-byte recoverable secp256k1 signature, 0x-hex: r ‖ s ‖ v.
signature_rsvThe same signature as an explicit {r, s, v} triple (v = 27 or 28), so you can ecrecover directly instead of trusting our packing.
pcr0SHA-384 measurement (bare hex, 48 bytes) of the enclave build that holds the signing key.
data_pubkeyCompressed secp256k1 public key of the data-signing key (0x-hex, 33 bytes).
addressEthereum-style address derived from data_pubkey. Your ecrecover output must equal it.
domainDomain-separation tag: "usenami-attested-data-v1". Prefixed to the canonical bytes before hashing.
verifyLink to this page.

2. How the digest is computed

digest = keccak256( "usenami-attested-data-v1" ‖ canonical_v1(data) )

canonical_v1 is RFC 8785 (JCS) with one hard extra rule: JSON numbers are forbidden. Every numeric in the payload is a decimal string — exactly what the database holds, so no value ever round-trips through a lossy float. Object keys sort by UTF-16 code units; duplicate keys are rejected. The domain tag is prefixed as raw ASCII bytes.

Parse the served data string and re-canonicalise it yourself — do not hash the served bytes directly. The enclave canonicalises what it signs, so your recompute must do the same. If your canonical bytes differ from what was signed, verification simply fails.

3. Recover the signer

Run ecrecover over the digest with the signature_rsv triple (v is 27/28). The recovered public key must equal data_pubkey and its derived address must equal address. As a final consistency check, the packed signature must be exactly r ‖ s ‖ v.

4. Pin the enclave (PCR0)

Steps 2–3 prove the payload was signed by the holder of the key behind address. To prove that key lives inside the published enclave build, compare the bundle's pcr0 against the attestation surfaces:

curl -s https://signer-demo.usenami.io:8443/attestation

5. Working example (Python)

Save a response as response.json and run the script below — it re-derives the digest, ecrecovers the signer, and cross-checks every identity field. It prints VERIFIED on a genuine bundle and raises on any tampering: a changed value inside data, a smuggled JSON number, a duplicate key, a wrong v, or a mismatched packed signature.

"""Verify a Usenami /v1/perp/attested-snapshot response — no trust in us required.

Dependencies:  pip install eth-keys eth-utils "eth-hash[pycryptodome]"
Usage:         python verify_attested_snapshot.py response.json
"""
import json
import sys

from eth_keys import keys
from eth_utils import keccak

DOMAIN = b"usenami-attested-data-v1"


def parse_no_duplicates(text: str):
    """Parse JSON, rejecting duplicate object keys (the enclave does the same)."""
    def hook(pairs):
        obj = {}
        for k, v in pairs:
            if k in obj:
                raise ValueError(f"duplicate key rejected: {k!r}")
            obj[k] = v
        return obj
    return json.loads(text, object_pairs_hook=hook)


def jcs_string(s: str) -> bytes:
    """RFC 8785 minimal string escaping: only \" \\ and C0 controls are escaped;
    everything else (incl. non-ASCII) is emitted as raw UTF-8."""
    out = ['"']
    for ch in s:
        if ch == '"':
            out.append('\\"')
        elif ch == "\\":
            out.append("\\\\")
        elif ch == "\b":
            out.append("\\b")
        elif ch == "\t":
            out.append("\\t")
        elif ch == "\n":
            out.append("\\n")
        elif ch == "\f":
            out.append("\\f")
        elif ch == "\r":
            out.append("\\r")
        elif ord(ch) < 0x20:
            out.append(f"\\u{ord(ch):04x}")
        else:
            out.append(ch)
    out.append('"')
    return "".join(out).encode("utf-8")


def canonical_v1(value) -> bytes:
    """RFC 8785 (JCS) + the attested-data hard rule: JSON numbers are forbidden —
    every numeric is a decimal string. Object keys sort by UTF-16 code units."""
    if value is None:
        return b"null"
    if value is True:
        return b"true"
    if value is False:
        return b"false"
    if isinstance(value, (int, float)):
        raise ValueError("canonical-v1: JSON numbers are forbidden in attested data")
    if isinstance(value, str):
        return jcs_string(value)
    if isinstance(value, list):
        return b"[" + b",".join(canonical_v1(v) for v in value) + b"]"
    if isinstance(value, dict):
        ordered = sorted(value.keys(), key=lambda k: k.encode("utf-16-be"))
        return (
            b"{"
            + b",".join(jcs_string(k) + b":" + canonical_v1(value[k]) for k in ordered)
            + b"}"
        )
    raise ValueError(f"unsupported JSON type: {type(value).__name__}")


def verify(bundle: dict) -> None:
    # 1. Recompute the digest from the raw 'data' text you were served.
    data = parse_no_duplicates(bundle["data"])
    digest = keccak(DOMAIN + canonical_v1(data))

    # 2. ecrecover from the (r, s, v) triple. v is 27/28; eth-keys wants 0/1.
    rsv = bundle["signature_rsv"]
    sig = keys.Signature(vrs=(rsv["v"] - 27, int(rsv["r"], 16), int(rsv["s"], 16)))
    pubkey = sig.recover_public_key_from_msg_hash(digest)

    # 3. The recovered identity must equal the published one.
    assert pubkey.to_address().lower() == bundle["address"].lower(), (
        f"address mismatch: recovered {pubkey.to_address()}, "
        f"bundle says {bundle['address']}"
    )
    assert "0x" + pubkey.to_compressed_bytes().hex() == bundle["data_pubkey"].lower(), (
        "recovered pubkey does not match data_pubkey"
    )

    # 4. The packed 65-byte signature must be exactly r ‖ s ‖ v.
    packed = "0x" + rsv["r"][2:].lower() + rsv["s"][2:].lower() + f"{rsv['v']:02x}"
    assert packed == bundle["signature"].lower(), "signature != r ‖ s ‖ v"

    print("VERIFIED")
    print(f"  signer address : {bundle['address']}")
    print(f"  enclave PCR0   : {bundle['pcr0'][:16]}…")
    print(f"  ticker / as_of : {data['ticker']} / {data['as_of']}")
    # schema v2 puts the signing instant INSIDE the signature, so this line is
    # attested, not metadata you have to take on trust.
    print(f"  signed_at      : {data['signed_at']}")


if __name__ == "__main__":
    with open(sys.argv[1]) as f:
        verify(json.load(f))

Questions, or a bundle that fails verification? [email protected] — a failing bundle is a bug on our side, and we want to see it.