Exosphere.ATProto.Repo.Commit (Exosphere v0.2.0)

Copy Markdown View Source

Repository commit signature verification.

Every repository commit is a DAG-CBOR object carrying a sig field: the raw ECDSA signature, in low-S form, over the SHA-256 of the unsigned commit (the same object with the sig field removed) encoded as canonical DAG-CBOR.

This module re-encodes the unsigned commit and verifies the signature against an account's signing key, tying together Exosphere.ATProto.CBOR, Exosphere.ATProto.Crypto, and Exosphere.ATProto.Identity.

Examples

# With an explicit public key + curve
:ok = Exosphere.ATProto.Repo.Commit.verify(commit, public_key, :secp256k1)

# Or resolve the signing key straight from a DID Document
:ok = Exosphere.ATProto.Repo.Commit.verify_with_document(commit, did_document)

Summary

Functions

Verify a decoded commit object against a public key.

Verify that a commit's data field (the MST root) matches a set of records.

Verify a commit using the signing key advertised in a DID Document.

Types

commit()

@type commit() :: %{optional(String.t()) => term()}

Functions

verify(commit, public_key, curve)

@spec verify(commit(), binary(), Exosphere.ATProto.Crypto.curve()) ::
  :ok | {:error, :missing_sig | :invalid_signature | term()}

Verify a decoded commit object against a public key.

The commit is the map produced by decoding the commit block (e.g. via Exosphere.ATProto.CBOR.decode/1 or extracted from a CAR file), with the data field as an Exosphere.ATProto.CID and sig as raw bytes.

Returns :ok, or {:error, reason} if the signature is missing, malformed, or invalid.

verify_data(commit, records)

@spec verify_data(commit(), Enumerable.t()) ::
  :ok | {:error, :data_mismatch | :missing_data | term()}

Verify that a commit's data field (the MST root) matches a set of records.

records is a path => CID map (or enumerable of {path, %CID{}}) of every record in the repository. The records are assembled into an MST and the resulting root CID is compared to the commit's data link, confirming the commit actually attests to exactly those records.

Combine with verify/3 to fully authenticate a repository: verify/3 proves the commit is signed by the account, and verify_data/2 proves the records match the signed root.

Returns :ok, {:error, :data_mismatch}, {:error, :missing_data}, or any error from MST construction.

verify_with_document(commit, doc)

@spec verify_with_document(commit(), Exosphere.ATProto.Identity.Document.t()) ::
  :ok | {:error, :missing_sig | :invalid_signature | :not_found | term()}

Verify a commit using the signing key advertised in a DID Document.