A treasury whose spend key is split with FROST, 2-of-3 for instance, makes receipts like any wallet. Any two signers sign with the receipt’s own randomizer; the signature is an ordinary SpendAuthSig, and the receipt doesn’t show which two signed.
Tested with the Zcash Foundation’s re-randomized FROST over Pallas (reddsa 0.5.2) in a unit test and conformance vectors, and on the Zcash public testnet: a 2-of-3 treasury (a testnet wallet’s spend key split by a trusted dealer, group key equal to its ak) signed a receipt for a real payment, and zceipt verify accepts it against the chain with its policy proof.

Policy proof

Plain threshold receipts prove spend authority. A policy proof (zip311p1) adds that the receipt was authorized under the treasury’s published key. The holders publish the verifiable-secret-sharing commitment C_0..C_{t−1} and the number of holders n. C_0 is the key’s ak. A receipt signed by any t carries rk = C_0 + [alpha]G for each spend. The proof is a Schnorr proof of knowledge of each spend’s alpha for rk − C_0, bound to the receipt’s digest, the commitment and a verifier’s challenge. The verifier learns “this payment was authorized under that t-of-n key”.
receipt.txt holds the receipt and the policy proof (zip311p1…); commitment.txt lists the commitment the treasury published, one point per line. Pin it.

What the commitment shows

The key is shared with a polynomial of degree t − 1, so any t of n holders, and no fewer, can sign; each holder checks its share against the commitment. It does not show the dealer discarded the whole key. With a trusted dealer that is a trust assumption; distributed key generation removes it. The proof binds the receipt’s key to C_0 and nothing else. Whoever holds the whole key can prove the same receipt under a commitment of any threshold with the same C_0. So the verifier takes the commitment from the treasury’s own publication and passes it with --policy-commitment; without that flag verify says the commitment is the proof’s own.
  • Key sets are n separate keys; a policy is one key held by n parties.
  • The signer-side flow is the one in spend authority: the proofs need only the viewing key, so a multisig signs a prepared receipt.
Code: crates/zceipt-core/src/policy.rs, crates/zceipt-core/tests/frost.rs.