# `.qsig` — Detached Signature Container (v1)

**Status:** Locked baseline (v1). This is the **normative** specification for the detached signature
container produced and consumed by Quantum‑Sign components.

## 1. Goals & Non‑Goals
- **Goals:** deterministic, compact, CBOR‑encoded, offline‑verifiable; support **multi‑signature** (e.g., ML‑DSA + SLH‑DSA), RFC 3161 timestamps, and CT‑style transparency proofs.
- **Non‑Goals:** embedding OS‑specific code‑signing metadata; mutating target files; transport encryption (handled separately).

## 2. Canonical CBOR Encoding
- Encoding: **CBOR (RFC 8949)**, **definite length** for all items (no indefinite‑length), **UTF‑8** text.
- Map keys: **sorted in bytewise lexicographic order**.
- Disallowed: floating‑point types; CBOR tags (except as reserved for future versions).
- Strings: normalized to NFC; times encoded as **RFC 3339 strings** (UTC, `Z` suffix).

## 3. Top‑Level Structure
CBOR **map** with the following keys (order‑insensitive, but encoded canonically):

| Key | Type | Required | Description |
|---|---|---|---|
| `v` | uint | yes | Container version. **Must be `1`.** |
| `alg` | tstr | yes | Primary signature algorithm profile (e.g., `mldsa-87`). |
| `digest` | map | yes | Content digest `{ "alg": tstr, "val": bstr }`. `alg` ∈ {`sha256`,`sha512`,`shake256`}. |
| `sig` | bstr | yes | Primary signature bytes over the **signing transcript** (see §4). |
| `co_sig` | array(map) | no | Additional signatures, each `{ "alg": tstr, "sig": bstr }`. |
| `tst` | bstr | no | RFC 3161 TimeStampToken **DER** bytes. |
| `tlog` | map | no | Transparency proof object (see §6). |
| `signer` | map | yes | Signer metadata `{ "kid": bstr, "claims": map }`. |
| `time` | tstr | yes | RFC 3339 UTC timestamp of signing. |
| `ds` | tstr | yes | Domain‑separation label. **Must be `quantum-sign-v1`.** |
| `meta` | map | no | Optional non‑security metadata (display‑only). |
| `x-…` | any | no | Reserved for private extensions; keys beginning with `x-` **must be ignored** by verifiers. |

### 3.1 `kid` (Key Identifier)
- Computed as `SHA‑256(pubkey_encoding)` of the primary signing public key, encoded as raw bytes (`bstr`).

## 4. Signing Transcript
The byte sequence to be signed is the **CBOR canonical encoding** of the tuple:
```
("qsig.v1", alg, digest.alg, digest.val, time, signer.kid)
```
- This binds the algorithm choice, content digest, signing time, and key identity.
- Co‑signatures repeat the same transcript **with their own `alg` value**.

## 5. Algorithm Identifiers
- `alg` values (primary and co‑signatures):
  - `mldsa-44`, `mldsa-65`, `mldsa-87`
  - `slh-dsa-XXX` (per chosen parameter set; e.g., `slh-dsa-128s`)
- `digest.alg`: `sha256`, `sha512`, or `shake256`.

## 6. Transparency Log Object (`tlog`)
CBOR map:
```
{
  "log_id": bstr,     # stable identifier for the log (public key digest)
  "leaf":   bstr,     # leaf hash committed to by the log
  "root":   bstr,     # signed tree head root
  "size":   uint,     # tree size for the STH
  "proof":  [ bstr* ],# Merkle inclusion proof nodes (left-to-right)
  "sth":    bstr      # serialized STH with signature (format defined by the log)
}
```
- The `leaf` is the hash of the **entry body**, which includes `digest` and `signer.kid` at minimum.
- Verifiers **must** validate inclusion (`leaf`→`root`) and optionally **consistency** proofs against a trusted `log_id`/public key.

## 7. Timestamp Token (`tst`)
- Raw DER of RFC 3161 `TimeStampToken`.
- Verifiers **must** validate the TSA certificate chain and token signature when a trust anchor is available; otherwise, treat as **unsigned metadata**.

## 8. Verification (Offline‑First)
Given an artifact `A` and signature `A.qsig`:
1. **Decode** CBOR with canonical checks (definite length, key ordering).
2. **Digest**: recompute `digest.alg(A)` and compare with `digest.val`.
3. **Transcript**: assemble as per §4.
4. **Signature**: verify `sig` under `alg` with the signer’s public key from the trust database keyed by `signer.kid`.
5. **Co‑signatures**: repeat step 4 for each element in `co_sig`.
6. **Timestamp (optional)**: validate `tst` if TSA trust is configured.
7. **Transparency (optional)**: validate `tlog` proofs against a trusted log key.

Verification **must succeed offline** with only: the `.qsig` file, the artifact bytes, and a local trust database.

## 9. Canonicalization Test Vectors (illustrative)
- `qs-format` ships a golden regression test (`tests::golden_sha256_digest`) whose fixed specimen encodes to SHA-256 digest `877519a8e00897c7214f9393bea0462f13eee190bdef1b952c432bc121560374`. Any schema change must update that digest intentionally.
- Additional fixtures (e.g., `"hello"` payloads) can be added as the encoder matures.

## 10. Versioning & Forward Compatibility
- `v` increments on **breaking** format changes.
- New optional fields may be added; unknown fields **must be ignored**.
- Private extensions live under `x-*` keys and must not affect verification outcomes.

## 11. Security Considerations
- Refuse non‑canonical encodings (indefinite lengths, duplicate keys, unexpected types).
- The `meta` object is **non‑security‑relevant** and must not influence verification.
- `time` is unauthenticated unless a valid `tst` is present.
