# `MetamorphicLog.Checkpoint`
[🔗](https://github.com/moss-piglet/metamorphic_log/blob/main/lib/metamorphic_log/checkpoint.ex#L1)

Transparency-log checkpoints (signed tree heads), in the
[C2SP tlog-checkpoint](https://github.com/C2SP/C2SP/blob/main/tlog-checkpoint.md)
format carried inside a `MetamorphicLog.Note`.

A checkpoint commits to a log's `origin`, `size`, and Merkle `root`. Verifying
one against trusted keys, then checking inclusion/consistency proofs *against
that verified checkpoint*, is the core monitor/auditor workflow.

# `t`

```elixir
@type t() :: %MetamorphicLog.Checkpoint{
  extensions: [String.t()],
  origin: String.t(),
  root: String.t(),
  size: non_neg_integer()
}
```

A parsed/verified checkpoint. `root` is base64-encoded.

# `parse`

```elixir
@spec parse(body_text :: String.t()) :: {:ok, t()} | {:error, String.t()}
```

Parse an **unverified** checkpoint body (no signature check).

Use this only when the signature has already been established out of band;
otherwise prefer `verify/2`. Returns `{:ok, %Checkpoint{}}` or
`{:error, reason}`.

# `sign_hybrid`

```elixir
@spec sign_hybrid(
  origin :: String.t(),
  size :: non_neg_integer(),
  root_b64 :: String.t(),
  name :: String.t(),
  secret_key_b64 :: String.t()
) :: {:ok, String.t()} | {:error, String.t()}
```

Build a checkpoint body and sign it with a hybrid PQ composite secret key in
one call, returning the complete C2SP signed-note text ready to publish.

`origin` is the log identity line; `size` the tree size; `root_b64` the
base64 of the exactly 32-byte RFC 6962 root at `size`; `name` the C2SP key
name (usually the origin); `secret_key_b64` the base64 composite secret key.

This is the one-call producer path for a checkpoint publisher: it shares the
core's `Checkpoint` + `sign_hybrid` code path, so it never hand-assembles the
byte layout. The verifier key derived from `secret_key_b64`'s public half
(`MetamorphicLog.VerifierKey.encode_hybrid/2`) verifies the produced note via
`verify/2`.

Returns `{:ok, note_text}` or `{:error, reason}` (malformed checkpoint —
empty origin or non-32-byte root — or a signing failure).

## Example

    {:ok, note} =
      MetamorphicLog.Checkpoint.sign_hybrid("origin/log", 10, root_b64, "origin/log", sk)

# `verify`

```elixir
@spec verify(note_text :: String.t(), trusted_vkeys :: [String.t()]) ::
  {:ok, t()} | {:error, String.t()}
```

Verify a signed-note `note_text` against `trusted_vkeys` and return the
enclosed checkpoint.

Returns `{:ok, %Checkpoint{}}` or `{:error, reason}`.

## Example

    {:ok, %MetamorphicLog.Checkpoint{size: size, root: root}} =
      MetamorphicLog.Checkpoint.verify(note_text, [vkey])

# `verify_consistency`

```elixir
@spec verify_consistency(
  older_note :: String.t(),
  newer_note :: String.t(),
  trusted_vkeys :: [String.t()],
  proof_b64 :: [String.t()]
) :: :ok | {:error, String.t()}
```

Verify both `older_note` and `newer_note` against `trusted_vkeys`, then verify
that the newer checkpoint is a consistent extension of the older one.

`proof` is a list of base64-encoded hashes. Returns `:ok` or
`{:error, reason}`.

# `verify_inclusion`

```elixir
@spec verify_inclusion(
  note_text :: String.t(),
  trusted_vkeys :: [String.t()],
  leaf_index :: non_neg_integer(),
  leaf_hash_b64 :: String.t(),
  proof_b64 :: [String.t()]
) :: :ok | {:error, String.t()}
```

Verify `note_text` against `trusted_vkeys`, then verify that `leaf_hash` is
included at `leaf_index` under that checkpoint's root.

`proof` is a list of base64-encoded sibling hashes. Returns `:ok` or
`{:error, reason}`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
