MetamorphicLog.Leaf (metamorphic_log v0.1.0)

Copy Markdown View Source

Canonical leaf encoding for the mosslet/key-history/v1 conformance instance.

This is the worked example of the engine's application-agnostic leaf layer: a signed, hash-chained key-history entry. The three functions here reproduce — byte-for-byte — the canonical encoding, the intra-chain entry hash, and the RFC 6962 leaf hash, identically across the Rust core, the browser WASM SDK, and this NIF. That cross-target parity is what lets a monitor recompute and compare a log built by browser clients.

Entry

An entry is a map with base64-encoded binary fields:

%{
  seq: 0,                     # u64 sequence number
  ts_ms: 1_700_000_000_000,   # u64 unix-ms timestamp
  enc_x25519: "...",          # base64 X25519 encryption public key
  enc_pq: "...",              # base64 ML-KEM encryption public key
  signing_pub: "...",         # base64 hybrid signing public key
  prev_entry_hash: nil        # base64 prev entry_hash, or nil for genesis
}

Canonical layout

u32_be(VERSION=1)
  || u64_be(seq) || u64_be(ts_ms)
  || lp(enc_x25519) || lp(enc_pq) || lp(signing_pub) || lp(prev_entry_hash)

where lp(x) = u32_be(byte_size(x)) || x and a nil prev_entry_hash encodes as lp(<<>>).

Return shape

Each function returns {:ok, value_b64} | {:error, reason}, with a ! variant that returns the value directly and raises on invalid input.

Summary

Types

A mosslet/key-history/v1 entry with base64-encoded binary fields. :prev_entry_hash is nil for the genesis entry.

Functions

Canonical byte encoding of a key-history/v1 entry, base64-encoded.

Intra-chain SHA3-512 entry hash of entry, base64-encoded.

RFC 6962 leaf hash — SHA-256(0x00 || canonical_bytes) — of entry, base64-encoded. This is the value placed in the Merkle tree.

Types

entry()

@type entry() :: %{
  :seq => non_neg_integer(),
  :ts_ms => non_neg_integer(),
  :enc_x25519 => String.t(),
  :enc_pq => String.t(),
  :signing_pub => String.t(),
  optional(:prev_entry_hash) => String.t() | nil
}

A mosslet/key-history/v1 entry with base64-encoded binary fields. :prev_entry_hash is nil for the genesis entry.

Functions

key_history_v1_canonical_bytes(entry)

@spec key_history_v1_canonical_bytes(entry()) ::
  {:ok, String.t()} | {:error, String.t()}

Canonical byte encoding of a key-history/v1 entry, base64-encoded.

Example

{:ok, canon} = MetamorphicLog.Leaf.key_history_v1_canonical_bytes(entry)

key_history_v1_canonical_bytes!(entry)

@spec key_history_v1_canonical_bytes!(entry()) :: String.t()

Bang form of key_history_v1_canonical_bytes/1.

key_history_v1_entry_hash(entry)

@spec key_history_v1_entry_hash(entry()) :: {:ok, String.t()} | {:error, String.t()}

Intra-chain SHA3-512 entry hash of entry, base64-encoded.

This is the value a later entry references as its :prev_entry_hash, chaining the history together.

key_history_v1_entry_hash!(entry)

@spec key_history_v1_entry_hash!(entry()) :: String.t()

Bang form of key_history_v1_entry_hash/1.

key_history_v1_rfc6962_leaf_hash(entry)

@spec key_history_v1_rfc6962_leaf_hash(entry()) ::
  {:ok, String.t()} | {:error, String.t()}

RFC 6962 leaf hash — SHA-256(0x00 || canonical_bytes) — of entry, base64-encoded. This is the value placed in the Merkle tree.

key_history_v1_rfc6962_leaf_hash!(entry)

@spec key_history_v1_rfc6962_leaf_hash!(entry()) :: String.t()

Bang form of key_history_v1_rfc6962_leaf_hash/1.