Skip to content

[ZIP 304] Sapling Address Signatures (signmessage/verifymessage support) #345

@daira

Description

@daira

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.)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions