MetamorphicLog.Checkpoint (metamorphic_log v0.1.5)

Copy Markdown View Source

Transparency-log checkpoints (signed tree heads), in the C2SP tlog-checkpoint 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.

Summary

Types

t()

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

Functions

Parse an unverified checkpoint body (no signature check).

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.

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

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

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

Types

t()

@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.

Functions

parse(body_text)

@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(origin, size, root_b64, name, secret_key_b64)

@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(note_text, trusted_vkeys)

@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(older_note, newer_note, trusted_vkeys, proof_b64)

@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(note_text, trusted_vkeys, leaf_index, leaf_hash_b64, proof_b64)

@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}.