Technical › FCMP++

SA+L: spend authority and key image

The generalized Schnorr protocol that replaces the "signature" in FCMP++

In short

SA+L (Spend Authorization + Linkability) is a small proof on Ed25519 for each input. It shows: "I know x and y for the rerandomized key Õ, and the published key image L equals x·I for the same output". Technically it's a generalized Schnorr protocol (GSP) — several Schnorr equations tied together by shared secrets.

Generalized Schnorr in one minute

Plain Schnorr proves knowledge of one x in one equation P = x·G. The generalized version proves knowledge of a vector of secrets (w₁, …, wₖ) satisfying several linear equations over points:

Y_j = Σ_k w_k · X_{j,k}    for each equation j

The protocol is the same as for one key:

  1. pick random α_k and publish A_j = Σ α_k·X_{j,k} for each equation;
  2. challenge c = Hs(everything published);
  3. responses s_k = α_k + c·w_k;
  4. check: Σ s_k·X_{j,k} = A_j + c·Y_j for each j.

The key detail: the same response s_k is used in every equation where w_k appears. So the verifier learns not just "knows some secrets" but "knows the same secrets for all equations". That's how spend authority and the key image get linked.

Which equations SA+L proves

Public: Õ, Ĩ, R, L and the generators G, T, U, V. The spender's secrets: x, y (output key) and r_o, r_i, r_r_i (the rerandomization paint). Simplified, SA+L proves the system:

Õ = x·G + (y + r_o)·T
R = r_i·V + r_r_i·T
L = x·Ĩ − (x·r_i)·U the last is L = x·(Ĩ − r_i·U) = x·I; the product x·r_i is introduced as a separate secret, and the link to R prevents faking it

The exact equations in the specification differ a bit (they carefully handle which products of secrets are needed and how to avoid leaks), but the idea is exactly this: one proof in which x both "opens" Õ and "produces" L.

Why not just a signature

In RingCT, CLSAG did three things at once: hid the input in a ring, proved spend authority and linked the key image. In FCMP++ the membership proof takes over the first job. Two remain — solved by a much simpler protocol. This gives:

  • small size — a few points and scalars per input;
  • role separation — the device holding the key (a hardware wallet) can compute SA+L, while a computer without the key builds the heavy membership proof;
  • forward secrecy — thanks to y·T in the key (see the overview);
  • groundwork for multisig — GSP's linear structure splits nicely between several signers (FROST-like schemes).

What gets signed

The challenge c includes a hash of the whole transaction (prefix, outputs, commitments), as in CLSAG. So SA+L also acts as a signature: change a single byte of the transaction after signing and the proof no longer verifies.

For the curious

Formal definitions are in Luke Parker's FCMP++ paper and in the Rust implementation (the monero-oxide project). The protocol and implementation went through external audits; links to the reports are collected in Monero Research Lab discussions on GitHub.