# Orange Anchor Interaction Patterns

**Check-in and Cosign — Protocol Specification**

*Version 1.0 — May 2026*

---

> **Core invariant.** Per-commitment production cost is positive and scales linearly with volume up to operational constants, under a stated, adversary-favourable threat model. The architectural contribution is cost preservation and attribution: production cost paid by a holder persists as attributable scarcity across every system that recognises the commitment. See *Orange Anchor White Paper v2.3* for the full argument.

---

## About This Document

This document specifies the two interaction patterns that make Orange Anchor commitments usable in practice: **check-in** and **cosign**. Both are defined at architectural level in the *Orange Anchor White Paper v2.3* §7; this document provides the protocol-level detail required to implement them.

The audience is platform integrators, application developers, and wallet/app developers building against the Orange Anchor construction. The *Orange Anchor Integration Brief v2.2* describes *why* to integrate; this document describes *how* the two patterns work at the protocol surface. Byte-level construction internals are specified in the reference implementation; this document specifies the interaction layer above them.

*Conformance language.* MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are used per RFC 2119 within normative claims.

*Relation to the Lexicon.* Terms used here are defined in the *Orange Anchor Lexicon v2.7*. *Holder* refers to the producer in their continuing role as the party presenting the commitment. *Cosigning party* refers to any service, platform, or verifier that accepts a commitment as collateral for a relationship.

---

## 1. Background and Scope

A collateral commitment, once produced and established on Bitcoin, is an artefact the holder can present to any party that recognises the Orange Anchor construction. That presentation takes one of two forms:

- **Check-in** — the holder presents the commitment as a credential to a system. The system verifies independently and applies its own policy.
- **Cosign** — the holder links the commitment to an existing account, credential, or identity by publishing a mutual signing record to the attribution index.

These are not competing patterns; they are complementary. Check-in is a point-in-time verification event. Cosign is a persistent linkage that any verifier can later discover. A holder may check in to a system and, in the same session or later, cosign to link the commitment to their account there.

Both patterns share the same foundation: verification depends on the Bitcoin chain and the commitment's own cryptographic structure for inclusion verification; full construction verification additionally requires the published Orange Anchor reference implementation. No issuer, identity provider, or third-party authority participates in the verification path.

---

## 2. The Check-in Pattern

### 2.1 Overview

Check-in is a challenge-response protocol. The verifying system issues a one-time challenge; the holder signs it with the key bound to their commitment; the system verifies the signature and the commitment. No session state is required beyond the ephemeral challenge. No third party participates.

The pattern is the digital analogue of presenting a signed credential: the holder proves both that they hold the private key associated with the commitment and that the commitment itself is valid against Bitcoin.

### 2.2 Actors

| Actor | Role |
|---|---|
| **Holder** | Party presenting the commitment. Holds the private key corresponding to `commitment_pubkey`. |
| **Verifier** | The system issuing the challenge and verifying the response. Applies its own acceptance policy. |

### 2.3 Protocol Steps

*Wire-format convention.* All JSON field names in protocol messages defined in this document MUST be **snake_case**. Canonical JSON serialisation per RFC 8785 applies; field names are part of the signed payload. A receiver implementation that expects camelCase (or any other casing) will fail signature verification because the canonical byte representation differs. The canonical field-name registry is maintained in *Orange Anchor Lexicon v2.7* §5b.

**Step 1 — Challenge issuance (Verifier → Holder)**

The verifier constructs a challenge object and delivers it to the holder. The challenge MUST be unique per interaction and MUST be time-bounded to prevent replay.

```json
{
  "action": "checkin",
  "nonce": "<32-byte cryptographically random hex>",
  "verifier_id": "<verifier's stable identifier — domain, DID, or pubkey>",
  "timestamp": "<ISO 8601 UTC>",
  "expires": "<ISO 8601 UTC — SHOULD be ≤ 5 minutes after timestamp>",
  "policy": {
    "require_attribution_check": false,
    "minimum_baru_score": 0
  }
}
```

The `verifier_id` identifies the verifier so the holder can confirm they are signing for the correct party. The `nonce` ensures the signed response cannot be replayed at another verifier or in a future session.

**Step 2 — Signing (Holder)**

The holder serialises the challenge object using canonical JSON (RFC 8785) and signs the result with the private key corresponding to `commitment_pubkey`. The holder MUST NOT sign a challenge whose `expires` timestamp has passed.

**Step 3 — Response (Holder → Verifier)**

The holder returns a signed response:

```json
{
  "challenge": { "...": "original challenge object verbatim" },
  "commitment_pubkey": "<33-byte compressed public key, hex>",
  "signature": "<64-byte BIP340 Schnorr signature over canonical-JSON challenge, hex>",
  "commitment": {
    "portable_proof_envelope": "<base64-encoded portable proof envelope>",
    "anchor_reference": "<deterministic anchor reference per BAVAI Operator Spec §4>"
  }
}
```

The response carries both the signed challenge and the commitment artefact itself, so the verifier can verify both in a single pass.

**Step 4 — Verification (Verifier)**

The verifier performs the following checks, in order. All MUST pass for the interaction to succeed.

1. **Challenge freshness.** The current time is before `expires`. The `nonce` has not been seen in any prior interaction (verifiers MUST maintain a nonce log for the challenge expiry window).
2. **Challenge integrity.** The `challenge` field in the response matches the challenge the verifier issued (byte-for-byte, canonical JSON).
3. **Signature validity.** The `signature` is a valid BIP340 Schnorr signature over the canonical-JSON-serialised `challenge`, verifiable against `commitment_pubkey`.
4. **Commitment inclusion.** The portable proof envelope's anchors appear at the claimed block heights on the Bitcoin chain (inclusion verification per *BAVAI Operator Specification v1.0* §7.3).
5. **Key binding.** The `commitment_pubkey` in the response matches the public key encoded in the commitment artefact.
6. **Policy check.** The verifier applies its own acceptance policy to the commitment — for example, minimum BARU score, attribution-event absence, or flagging check against BAVAI.

Steps 1–5 are deterministic and protocol-level. Step 6 is verifier-local and policy-defined.

**Step 4a — Verification scope (normative clarification)**

The checks specified in Step 4.1–4.5 perform **inclusion verification**: they confirm that the holder controls the commitment private key, that the challenge has not been replayed, and that the commitment's anchor transactions exist on Bitcoin at the claimed block heights. They do **not** perform **construction verification** — i.e. they do not confirm that the bracketed work (memory-hard computation, VDF, sensor witnessing) underlying the commitment was performed faithfully.

Verifiers requiring construction-quality assurance MUST additionally either (a) consume a BARU score from a trusted audit operator at Step 4.6 (policy layer), or (b) perform full construction verification using the Orange Anchor reference implementation against the holder's verification package (*BAVAI Operator Specification v1.0* §7.4). Verifiers SHOULD document, in their published acceptance policy, which of these two paths they apply.

**Step 5 — Outcome**

The verifier signals acceptance or rejection. On acceptance, the verifier MAY record a cosigning assertion (§3) to create a persistent verifiable linkage, or MAY operate statelessly, relying only on future re-presentation of the commitment.

### 2.4 Security Properties

**Replay prevention.** The nonce is single-use and time-bounded. A signed challenge is valid for at most the `expires` window and only against the issuing verifier's `verifier_id`.

**Commitment binding.** The signature ties a specific private key to the interaction. The key-binding check (Step 4.5) ties that private key to the commitment artefact. An attacker presenting a commitment that does not match their key fails Step 4.5.

**No third-party dependency.** Verification in Steps 4.1–4.5 depends only on the Bitcoin chain and the artefact the holder provides, for the scope of inclusion verification clarified in Step 4a. The verifier needs no live connection to any operator for Steps 1–5; it MAY query an operator for Step 6 policy checks (BARU score, attribution events) and SHOULD treat operator unavailability as a policy question rather than a verification failure. **Construction verification** (confirming that the bracketed work was performed faithfully) additionally depends on the published Orange Anchor reference implementation; see Step 4a.

**Privacy note.** The challenge response is visible to the verifier, who learns the `commitment_pubkey` and can later correlate it with other interactions at the same or other verifiers. Holders who require unlinkability across verifiers should not use the same commitment at multiple verifiers. This is a structural property of the architecture, not a defect; the White Paper §7 notes it explicitly.

---

## 3. The Cosign Pattern

### 3.1 Overview

Cosign is a linkage-publication protocol. The holder produces a dual-signed linking record that associates the commitment's key with an external identity's key, and publishes that record as an attribution event to the BAVAI. Any verifier later querying either key can discover the linkage and verify it independently against the Bitcoin-anchored index root.

Cosign creates a persistent, public, verifiable association. It is appropriate where the holder *wants* the linkage to be discoverable — for example, linking a commitment to a social-network key to allow others to verify the connection. Holders who do not want the linkage discoverable should not publish it.

### 3.2 Actors

| Actor | Role |
|---|---|
| **Holder** | Party linking the commitment to an external identity. Holds the commitment private key. |
| **External identity** | The account, credential, or identity being linked. Must be capable of signing canonical messages with a private key. |
| **Publisher** | Party writing the attribution event to the BAVAI. MAY be the holder, the external identity, or an operator acting on their behalf. Anyone may publish. |
| **Verifier** | Any party later querying the BAVAI to find and verify the linkage. |

At MVP, holder and external identity are typically the same person operating two keys (the commitment key and, for example, a Nostr npub or DID key). The publisher is typically the holder or the Orange Pages operator.

### 3.3 Protocol Steps

**Step 1 — Canonical linking message construction**

The holder constructs the canonical linking message. The message MUST be deterministic and unambiguous; both keys sign the identical canonical form.

```json
{
  "action": "cosign",
  "commitment_pubkey": "<33-byte compressed public key, hex>",
  "external_pubkey": "<external identity public key — format depends on key type>",
  "external_key_type": "<'nostr_npub' | 'did' | 'pgp' | 'bitcoin_pubkey' | ...>",
  "purpose": "<human-readable description of the linkage, e.g. 'Link to Nostr identity npub1...'>",
  "timestamp": "<ISO 8601 UTC>",
  "nonce": "<32-byte hex — prevents linkage replay if key pair is reused>"
}
```

The `purpose` field is informational; verifiers MAY display it but MUST NOT rely on it for security decisions.

**Step 2 — Dual signing (Holder)**

The holder serialises the canonical linking message (RFC 8785) and signs it twice:

1. **Commitment signature** — signed with the commitment private key (BIP340 Schnorr).
2. **External identity signature** — signed with the external identity private key using the algorithm appropriate to `external_key_type` per the table below.

*Supported `external_key_type` values at v1.0:*

| `external_key_type` | Curve | Signature algorithm | Notes / example DID methods |
|---------------------|-------|---------------------|-----------------------------|
| `nostr_npub`        | secp256k1 | BIP340 Schnorr | Nostr public keys |
| `bitcoin_pubkey`    | secp256k1 | BIP340 Schnorr | Native Bitcoin keys |
| `did:key:ed25519`   | Ed25519 | EdDSA (RFC 8032) | did:key (Ed25519 form), did:ion |
| `did:key:secp256k1` | secp256k1 | BIP340 Schnorr | did:key (secp256k1 form), did:ethr, did:btcr |
| `did:web:p256`      | NIST P-256 | ECDSA over SHA-256 | did:web, enterprise DID deployments |
| `pgp`               | (per PGP key type) | (per PGP key type) | OpenPGP signatures |

DID methods not enumerated above are not supported by v1.0 of the cosign protocol. Support is extensible via future versions of this document; an implementation MUST refuse to verify a cosign record whose `external_key_type` it does not recognise rather than treat it as a verification success.

Both signatures are over the identical canonical serialisation of the linking message.

**Step 3 — Attribution event construction**

The publisher constructs the BAVAI attribution event. Using the key encoding defined in *BAVAI Reference v1.0*:

```
KEY   = cosign_indicator (1 byte, value 0x02) || commitment_pubkey (33 bytes)
      = 34 bytes

VALUE = external_pubkey
      + external_key_type (length-prefixed)
      + commitment_signature (64 bytes)
      + external_signature (variable, algorithm-dependent)
      + timestamp (4 bytes)
      + nonce (32 bytes)
```

The full canonical linking message is also preserved off-chain by the publisher for verifier retrieval.

**Step 4 — Publication**

The publisher writes the attribution event to the BAVAI tree for the current epoch. At epoch close, the operator commits the Merkle root to Bitcoin via OP_RETURN. Anyone may publish; the publisher needs no protocol permission or operator delegation.

**Step 5 — Verification (Verifier)**

Any verifier wishing to confirm a cosign linkage between a commitment and an external identity:

1. Constructs the lookup key: `cosign_indicator || commitment_pubkey`.
2. Queries any operator for the value and Merkle proof at that key in the relevant epoch.
3. Reads the OP_RETURN root for the epoch from Bitcoin directly.
4. Verifies the Merkle proof against the on-chain root.
5. Reconstructs the canonical linking message from the retrieved value.
6. Verifies the commitment signature against `commitment_pubkey`.
7. Verifies the external signature against `external_pubkey` using the appropriate algorithm for `external_key_type`.

Steps 3–7 are fully local. The operator can refuse to serve (Steps 2 and 3) but cannot forge a valid Merkle proof against the Bitcoin-committed root.

### 3.4 Linkage Discovery

A verifier may discover a cosign linkage from either side:

- **From the commitment key** — look up `cosign_indicator || commitment_pubkey` to find any linked external identities.
- **From the external key** — an operator MAY maintain a reverse index keyed by external pubkey. The BAVAI structure does not require this; it is an operator-level service.

A commitment MAY be cosigned to multiple external identities; each produces a separate attribution event. An external identity MAY be linked to multiple commitments.

### 3.5 Security Properties

**Mutual consent.** Both the commitment key and the external identity key must sign the identical message. An attacker who holds only one key cannot produce a valid cosign record for the other.

**Non-repudiation.** The dual-signed record is permanently published in the BAVAI, verifiable against the Bitcoin-anchored root. Neither party can quietly retract it; they may publish a revocation record (a separate attribution event of type `cosign_revocation_indicator` — the byte value `0x03` in the BAVAI key construction per *BAVAI Reference v1.0* and *BAVAI Operator Specification v1.0* §6.4), which verifiers can discover and apply under their own policy.

**Anyone-can-publish.** The publisher of the attribution event is not required to be either key-holder. A verifier wishing to record an observed linkage (for example, an operator who has independently verified the dual-signed message and wants to publish it for others) may do so. The published record is verifiable against the Bitcoin root regardless of who wrote it.

**Privacy note.** Published cosign records are permanently public and discoverable. The linkage between `commitment_pubkey` and `external_pubkey` becomes observable by any party querying the BAVAI. Holders must treat cosign as an irreversible public act. Revocation removes the linkage from *future* verifier consideration under policies that respect revocations; it does not remove the original record from the chain or from historical index snapshots.

---

## 4. Transport and Delivery

The interaction patterns specify the message structures and verification steps. They are transport-agnostic. The following delivery mechanisms are defined at MVP.

### 4.1 Nostr DM (NIP-17)

**Recommended for mobile.** The verifier encodes the challenge or linking message as a NIP-17 encrypted direct message to the holder's Nostr key. The holder's Android application receives and processes it. The signed response is returned as a NIP-17 reply.

This transport requires the holder to have a Nostr key configured in the Android application. It is the primary mechanism for the Orange Anchor Android app and for the Orange Anchor Widget when the holder is on mobile.

### 4.2 QR Code

**For in-person or cross-device flows.** The challenge or linking message is encoded as a QR code displayed by the verifier. The holder scans it with the Android application, which decodes, signs, and presents the response via Nostr DM, deep link, or manual copy-paste.

### 4.3 Deep Link

**For same-device flows.** The challenge or linking message is encoded in an `orange-anchor://` deep link. Tapping the link opens the Android application, which decodes, signs, and returns the response via callback URL or copy-paste.

### 4.4 Manual Copy-Paste

**Air-gapped fallback.** The challenge JSON is copied by the holder into the Android application; the signed response JSON is copied back. Suitable for high-security contexts and testing.

---

## 5. Policy Layer

Verification (§2.3 Step 4.1–4.5 and §3.5 Steps 3–7) is deterministic. Policy (§2.3 Step 4.6) is verifier-local. The two must not be conflated.

A verifier's policy determines:

- **Minimum BARU score.** The verifier may require a minimum audit score from a trusted operator before accepting a commitment.
- **Attribution event filtering.** The verifier may reject commitments with open flags from specific operators or apply weighted policies across multiple operators.
- **Commitment age.** The verifier may decline commitments established before a certain block height (e.g., requiring a freshly produced commitment for high-stakes contexts).
- **Operator trust.** The verifier chooses which operators' signed records it considers. It may operate against the Bitcoin chain alone, trust one operator, or compose multiple operators' records under its own policy.
- **Flag-spam handling.** A verifier SHOULD weight attribution events by the production cost of the publishing commitment and MAY apply rate limits per publisher per epoch, per the recommended policy in *BAVAI Operator Specification v1.0* §6.4.8. Treating all flags as equal regardless of publisher cost exposes the verifier to cheap-flagging attacks.

Policy decisions are made after successful verification. A commitment that passes Steps 4.1–4.5 is cryptographically valid; whether it is *acceptable* for a given relationship is the verifier's decision alone.

---

## 6. Relationship to Other Documents

| Document | Relationship |
|---|---|
| *Orange Anchor White Paper v2.3* §7 | Architectural description of both patterns — upstream, authoritative on intent |
| *BACC v1.9* §4 | Interaction and verification model — architectural layer |
| *BAVAI Reference v1.0* | Key encoding and Merkle structure for cosign attribution events |
| *BAVAI Operator Specification v1.0* §7.3–§7.5 | Portable proof envelope and signed-record formats consumed by both patterns |
| *Orange Anchor Integration Brief v2.2* | Why platforms integrate; maps check-in and cosign to platform use cases |
| *Orange Anchor Widget Technical Specification v0.1* | Embeddable implementation of both patterns for websites |
| *Orange Anchor Lexicon v2.7* | Canonical definitions for all terms used here |

---

*Orange Anchor Interaction Patterns — Check-in and Cosign Protocol Specification. Version 1.0, May 2026.*
