MatterEx.Crypto.SPAKE2Plus (matter_ex v0.3.0)

Copy Markdown View Source

SPAKE2+ implementation for Matter PASE commissioning.

Uses P-256 curve with Matter-specific M and N points per Matter spec section 3.10 and RFC 9383.

Summary

Functions

Compute L = w1 * G from a 32-byte w1 scalar. Returns 65-byte SEC1 point.

Compute SPAKE2+ verifier from passcode (done once, stored on device).

Prover (commissioner) finish: given pB from verifier, derive session keys.

Prover (commissioner) start: generate pA = xG + w0M.

Verifier (device) respond: given pA from prover, compute pB and derive session keys.

Constant-time comparison of expected vs received confirmation MAC (cA or cB).

Functions

compute_l(w1_binary)

@spec compute_l(binary()) :: binary()

Compute L = w1 * G from a 32-byte w1 scalar. Returns 65-byte SEC1 point.

compute_verifier(passcode, salt, iterations)

@spec compute_verifier(non_neg_integer(), binary(), pos_integer()) :: map()

Compute SPAKE2+ verifier from passcode (done once, stored on device).

Returns %{w0: binary, w1: binary, l: binary} where:

  • w0, w1 are 32-byte scalars (mod n)
  • l is the SEC1 encoded point w1 * G (65 bytes)

prover_finish(map, pb_encoded, w1_binary, opts \\ [])

@spec prover_finish(map(), binary(), binary(), keyword()) :: {:ok, map()}

Prover (commissioner) finish: given pB from verifier, derive session keys.

Takes the prover_context from prover_start/2, the verifier's encoded public share, and the 32-byte w1 scalar. Returns {:ok, keys} with the same key map as verifier_respond/3.

Options:

  • :context — override the transcript context string (default: "CHIP PASE V1 Commissioning")
  • :prover_id — prover identity for transcript (default: empty)
  • :verifier_id — verifier identity for transcript (default: empty)

prover_start(w0_binary, opts \\ [])

@spec prover_start(
  binary(),
  keyword()
) :: {binary(), map()}

Prover (commissioner) start: generate pA = xG + w0M.

Takes a 32-byte w0 scalar. Returns {pA_encoded, prover_context} where prover_context is an opaque map passed to prover_finish/4.

Options:

  • :random_scalar — inject a fixed scalar for deterministic testing

verifier_respond(pa_encoded, map, opts \\ [])

@spec verifier_respond(binary(), map(), keyword()) :: {binary(), map()}

Verifier (device) respond: given pA from prover, compute pB and derive session keys.

Takes the prover's encoded public share and a verifier map %{w0: binary, l: binary}. Returns {pB_encoded, keys} where keys contains :ke, :ka, :kca, :kcb, :ca, :cb.

Options:

  • :random_scalar — inject a fixed scalar for deterministic testing
  • :context — override the transcript context string (default: "CHIP PASE V1 Commissioning")
  • :prover_id — prover identity for transcript (default: empty)
  • :verifier_id — verifier identity for transcript (default: empty)

verify_confirmation(expected, received)

@spec verify_confirmation(binary(), binary()) :: :ok | {:error, :confirmation_failed}

Constant-time comparison of expected vs received confirmation MAC (cA or cB).