-
Notifications
You must be signed in to change notification settings - Fork 166
Description
From zcash/zcash#1770 (comment) :
I confirmed that we can use the Sapling Spend circuit without modification to support signing.
The signer creates a fake note (with value 1 zatoshi; not zero) and a Spend proof for a fake commitment tree that has this note's commitment at position 0. It also reveals the opening of the fake note commitment, and a signature verifiable by the RedJubjub verification key rk that is a public input to the proof. This shows that the signer is authorized to spend for the diversified address corresponding to (gd, pkd) in the note commitment.
So, a signature is (d, pkd, rcm, cv, rt, nf, rk, π, σ, M) such that:
- gd = DiversifyHash(d) ≠ ⊥
- the same point validity checks are applied as for a Spend description
- ZKSpend.Verify((cv, rt, nf, rk), π) = 1
- NoteCommitSaplingrcm(reprJ(gd), reprJ(pkd), 1) = cm
- rt is the anchor of a fake Merkle tree with cm at position 0 (and no other entries)
- SpendAuthSig.Verifyrk(M, σ) = 1
The size overhead, excluding the message, of such a signature is 43 (size of Sapling diversified address) + 32 (size of rcm) + 384 (size of Spend description) = 459 bytes. It could be 43 + 32 (size of rk) + 192 (size of proof) + 64 (size of RedJubjub signature) = 331 bytes if we used a dedicated circuit that made (gd, pkd) public and so didn't need rcm, cv, rt or nf.
This is a non-consensus feature that does not block Sapling, but takes advantage of it. (There was no way to implement signmessage/verifymessage for Sprout z-addresses.)