Zcash中的signatures

1. 引言

Zcash Protocol Specification 中,约定对signature是“validate”,对zk-SNARK proof是“verify”。

Zcash的交易中可以像 Bitcoin 一样,包含:

  • transparent inputs
  • transparent outputs
  • scripts

同时,Zcahs的隐私交易中还可以包含:

  • JoinSplit descriptions
  • Spend descriptions (shielded input)
  • Output descriptions (shielded output)

The nullifiers of the input notes are revealed (preventing them from being spent again) and the commitments of the output notes are revealed (allowing them to be spent in future). Zcash隐私交易中还包含:

  • computationally sound zk-SNARK proofs
  • signatures

以上内容主要用于证明以下内容(hold except with insignificant probability):
(1)对于每一个shielded input:

  • there is a revealed value commitment to the same value as the input note;
  • if the value is nonzero, some revealed note commitment exists for this note;(即在note commitment tree中存在该input note commitment?)
  • the prover knew the proof authorizing key of the note;
  • the nullifier and note commitment are computed correctly。

(2)对于每一个shielded output:

  • there is a revealed value commitment to the same value as the output note;
  • the note commitment is computed correctly;
  • it is infeasible to cause the nullifier of the output note to collide with the nullifier of any other note.

此外,还对以下信息进行check:

  • 在Sprout的JoinSplit statement中还额外包含an explicit balance check。
    而在Sapling中,the value commitments corresponding to the inputs and outputs are checked to balance (together with any net transparent input or output) outside the zk-SNARK

为了确保未经授权的一方对交易进行篡改,还增加了一些措施:

  • 除zk-SNARK之外,会check input notes的nullifiers had not already been revealed (即 they had not already been spent)。

Shielded payment address 中包含的transmission key p k d pk_d pkd 可用于 a “key-private” asymmetric encryption scheme。所谓"key-private"是指,ciphertexts中不会泄露其加密key的信息,只对拥有加密key对应private key(此处也可称为receiving key)的一方可见。该机制主要用于communicate encrypted output notes on the block chain to their intended recipient,拥有receiving key的一方可扫描区块链来获取notes addressed to them 并 decrypt those notes。

在Sapling中,每一个spending key都有相应的full viewing key,full viewing key可用于recognize both incoming and outgoing notes without having spend authority。具体是通过每个Output description中额外的ciphertext—— C o u t C^{out} Cout 来实现的。

Zcash中的隐私属性的基本机制为:

  • 当a note is spent,Spender仅需prove that some commitment for it had been revealed, without revealing which one。

这就意味着,a spent note cannot be linked to the transaction in which it was created。

从adversary的角度来看,意味着a spent note是无法与一笔交易中的某个note input建立关联的。因为在该笔交易的note traceability set中,包含了all previous notes that the adversary does not control or know to have been spent。而 CoinjoinCryptoNote 中的private payment 实现是基于mixing of a limited number of transactions,因此对应的note traceability sets更小。

“nullifiers”有助于防止双花:区块链上的每个note仅有一个valid nullifier,因此,若尝试spend a note twice,则意味着将reveal the nullifier twice,相应的第二笔交易将会被reject。

a note 的nullifier表示为 n f nf nf

Sapling note的nullifier是由 ρ \rho ρ值 和 接收方 发送方 的nullifier deriving key n k nk nk派生出来的。

A note is spent by proving knowledge of ( ρ , a k , n s k ) (\rho,ak,nsk) (ρ,ak,nsk) in zero knowledge,同时对外公开该note的nullifier n f nf nf值,借助 n f nf nf可防止双花问题。

同时,Sapling中还需要a spend authorization signature,以用于demonstrate knowledge of a s k ask ask

每笔交易中有一系列的Spend description和一系列的Output description。

为了保证平衡,需使用Pedersen commitment的同态属性来支持相应的加法和减法运算,即 C o m ( v 1 ) + C o m ( v 2 ) = C o m ( v 1 + v 2 ) Com(v_1)+Com(v_2)=Com(v_1+v_2) Com(v1)+Com(v2)=Com(v1+v2)等。

平衡的实现可为:
将所有shielded inputs的value commitments相加,然后减去所有的shielded outputs的value commitments,最后使用a Sapling binding signature来证明the result commits to a value consistent with the net transparent value change。
这种方式有助于使所有的zk-SNARK statements相互独立,从而增加precomputation的机会。

Sapling中没必要支持interstitial treestate,因为某笔交易中的Spend transfer不能 spend同一笔交易内的任何shielded outputs。这种限制并不麻烦,与 Sprout中要求每笔JoinSplit transfer必须独自balance 不同,Sapling中仅要求整笔交易balance即可。

注意,交易中的 Spend transfer和Action transfer 必须与其 v b a l a n c e S a p l i n g v^{balanceSapling} vbalanceSapling 一致,该值具体定义见“Balance and Binding Signature(Sapling)”。

每个Spend description的anchor必须指向某earlier block的final Sapling treestate。

1.1 SIGHASH Transaction Hashing

Bitcoin和Zcash 使用 signatures and/or non-interactive proofs associated with transaction inputs 来 authorize spending。

由于这些signatures or proofs可在不同的交易中重放(replay),因此需要将其 “bind” to 指定的交易。具体的bind方法为:

  • 将交易和specific input进行hash,将hash结果作为 SIGHASH transaction hash 用于Spend authorization。

transparent inputs、Sprout JoinSplit transfer inputs 和 Sapling Spend transfer inputs 的authorization含义有所不同,但是指定的transaction version,其使用相同的 SIGHASH transaction hash 算法。

在Zcash中,其BCTV14 proving system和Groth16 proving system 均为malleable的,即意味着,不知道某proof所有auxiliary inputs的adversary,可创建a new proof involving related auxiliary inputs。具体见论文 DSDCOPS2001——Robust Non-Interactive Zero Knowledge.
可将其理解为类似于encryption scheme的malleability attack——adversary可malleate a ciphertext in order to create an encryption of a related plaintext, without knowing the original plaintext。

Zcash中设计了 “Balance and Binding Signature (Sapling)” 和 “Spend Authorization Signature (Sapling)” 可减轻malleability attack。

为了支持 combining spend authorizations from different sources,Bitcoin中定义了多个SIGHASH 类型来cover various parts of a transaction:[Bitcoin-SigHash]

  • “SIGHASH_ALL”
  • “SIGHASH_NONE”
  • “SIGHASH_SINGLE”

其中 SIGHASH_ALL 用于 JoinSplit signature、spend authorization signature、Sapling binding signature 这些Zcash-specific signature中。
注意,在Zcash中,SIGHASH transaction hash中不关联transparent input,因此hash运算中排出了交易中的所有non-Zcash-specific中的scriptSig fields。简言之,就是SIGHASH中不包含transparent input/output信息。

SIGHASH算法的演变路线为:

  • 原始的SIGHASH算法 [ZIP-76] —— for version 1 和 version 2 transaction,存在 [ZIP-143] 中所指出的Bitcoin deficiencies问题,Zcash在Overwinter升级中已对该算法进行了改进。
  • Overwinter升级后,Sapling升级前 的 SIGHASH算法 [ZIP-143] ——for version 3 transaction。
  • Sapling中的SIGHASH算法 [ZIP-243] —— for version 4 transaction。

2. Signature

Signature scheme S i g Sig Sig 的定义为:

  • S i g . P r i v a t e Sig.Private Sig.Private:为signing key。
  • S i g . P u b l i c Sig.Public Sig.Public:为validating key。【我们需要有不同的signing key generation和validating key derivation算法来支持“Sapling Key Components”中的key derivation,而不是传统的combined key pair generation算法: S i g . G e n : ( ) → R S i g . P r i v a t e × S i g . P u b l i c Sig.Gen:()\rightarrow_R Sig.Private\times Sig.Public Sig.Gen:()RSig.Private×Sig.Public。】
  • S i g . M e s s a g e Sig.Message Sig.Message:为message。
  • S i g . S i g n a t u r e Sig.Signature Sig.Signature:为signature。
  • S i g . G e n P r i v a t e : ( ) → R S i g . P r i v a t e Sig.GenPrivate:()\rightarrow_R Sig.Private Sig.GenPrivate:()RSig.Private:为randomized signing key generation 算法。
  • S i g . D e r i v e P u b l i c : S i g . P r i v a t e → S i g . P u b l i c Sig.DerivePublic: Sig.Private\rightarrow Sig.Public Sig.DerivePublic:Sig.PrivateSig.Public:为injective validating key derivation算法。
  • S i g . S i g n : S i g . P r i v a t e × S i g . M e s s a g e → R S i g . S i g n a t u r e Sig.Sign: Sig.Private\times Sig.Message\rightarrow_R Sig.Signature Sig.Sign:Sig.Private×Sig.MessageRSig.Signature:为randomized signing 算法。
  • S i g . V a l i d a t e : S i g . P u b l i c × S i g . M e s s a g e × S i g . S i g n a t u r e → B Sig.Validate: Sig.Public\times Sig.Message\times Sig.Signature\rightarrow \mathbb{B} Sig.Validate:Sig.Public×Sig.Message×Sig.SignatureB:为validating算法。

因此,对于任意的signing key s k ← R S i g . G e n P r i v a t e ( ) sk\leftarrow_R Sig.GenPrivate() skRSig.GenPrivate(),其相应的validating key为 v k = S i g . D e r i v e P u b l i c ( s k ) vk=Sig.DerivePublic(sk) vk=Sig.DerivePublic(sk),对于任何 m : S i g . M e s s a g e m:Sig.Message m:Sig.Message的签名 s : S i g . S i g n a t u r e ← R S i g . S i g n s k ( m ) s: Sig.Signature\leftarrow_R Sig.Sign_{sk}(m) s:Sig.SignatureRSig.Signsk(m),有 S i g . V a l i d a t e v k ( m , s ) = 1 Sig.Validate_{vk}(m,s)=1 Sig.Validatevk(m,s)=1

Zcash中采用了4种signature scheme:

  • 1)一种script signature scheme用于对类似Bitcoin中的OP_CHECKSIG 和 OP_CHECKMULTISIG script operation进行validate。【采用的是签名机制为ECDSA on the secp256k1 curve。】
  • 2)一种称为 JoinSplitSig,用于对包含至少一个JoinSplit description的交易进行签名。【JoinSplitSig中采用的签名机制为Ed25519。】
  • 3)一种称为 SpendAuthSig,用于对Spend transfer进行authorization签名。【采用的是基于Jubjub curve的RedDSA签名机制。】
  • 4)一种称为BindingSig。Sapling binding signature用于enforce balance of Spend transfers和Output transfers,同时用于防止重放攻击(to prevent their replay across transactions)。【采用的是基于Jubjub curve的RedDSA签名机制。】

SU-CMA security要求 不知道private key的adversary,无法forge a distinct signature on a previously seen message。也就是说,JoinSplit signature和Sapling binding signature 在 BIP-62 意义上是nonmalleable的。

SpendAuthSig 的粒度在每个spend description【用每个spender(不同)的 r s k rsk rsk对相同的transaction S i g H a s h SigHash SigHash进行签名】,BindingSig 的粒度在每笔交易【用 b s k S a p l i n g bsk^{Sapling} bskSapling对transaction S i g H a s h SigHash SigHash进行签名】。Sapling中的每一笔交易,都由一系列的Spend descriptions和一系列的Output descriptions组成。

2.1 script signature scheme

Script signature scheme中,采用的是签名机制为ECDSA on the secp256k1 curve。

2.2 JoinSplitSig

JoinSplitSig中采用的签名机制为Ed25519。

JoinSplitSig的安全要求为:

  • 必须在(non-adaptive)Chosen Message Attack (SU-CMA)情况下具有Strongly Unforgeability。【即允许an adversary 获取chosen messages的signatures,而要求其无法forge a previously unseen valid (message, signature) pair without access to the signing key。】

对于每一个包含JoinSplit description的交易,每次都会生成新的signature key pair。由于每组key pair仅用于1个signature,对于JoinSplitSig来说,这种one-time signature scheme就足够了。这也是为啥其安全要求中仅需满足 security against non-adaptive chosen message attack 的原因。
而Zcash在JoinSplitSig的实际实现时,设计的scheme甚至支持security under adaptive attack even when multiple signatures are signed under the same key。

2.3 SpendAuthSig

SpendAuthSig采用的是基于Jubjub curve的RedDSA签名机制。

SpendAuthSig的安全要求为:

  • 见“Signature with Re-Randomizable Keys”。

每笔交易中可包含0个或多个Spend description。每个Spend description均需authorized by a signature——spend authorization signature S p e n d A u t h S i g S a p l i n g SpendAuthSig^{Sapling} SpendAuthSigSapling
每笔交易中可包含0个或多个Output description,没有signature 关联 Output description。

要求the spend authorization signature必须为valid S p e n d A u t h S i g S a p l i n g SpendAuthSig^{Sapling} SpendAuthSigSapling signature over S i g H a s h SigHash SigHash using r k rk rk as the validating key,即 S p e n d A u t h S i g S a p l i n g . V a l i d a t e r k ( S i g H a s h , s p e n d A u t h S i g ) = 1 SpendAuthSig^{Sapling}.Validate_{rk}(SigHash,spendAuthSig)=1 SpendAuthSigSapling.Validaterk(SigHash,spendAuthSig)=1

2.4 BindingSig

BindingSig采用的是基于Jubjub curve的RedDSA签名机制。

BindingSig的安全要求有:

  • 见“Signature with Signing Key to Validating Key Monomorphism”。
  • 必须在(non-adaptive)Chosen Message Attack (SU-CMA)情况下具有Strongly Unforgeability。【即允许an adversary 获取chosen messages的signatures,而要求其无法forge a previously unseen valid (message, signature) pair without access to the signing key。】

对于每一笔包含Spend description或Output description的交易,都有相应的BindingSig。
BindingSig与JoinSplitSig类似,只是其key derived from the randomness of value commitments。其具有与freshly generated key pairs相同的distribution。

3. 用于 SpendAuthSig 的 Signature with Re-Randomizable Keys

具有re-randomizable keys的 signature scheme S i g Sig Sig 中 额外定义了:

  • S i g . R a n d o m Sig.Random Sig.Random:为randomizer。
  • S i g . G e n R a n d o m : ( ) → R S i g . R a n d o m Sig.GenRandom:()\rightarrow_R Sig.Random Sig.GenRandom:()RSig.Random:为randomizer generator。
  • S i g . R a n d o m i z e P r i v a t e : S i g . R a n d o m × S i g . P r i v a t e → S i g . P r i v a t e Sig.RandomizePrivate:Sig.Random\times Sig.Private\rightarrow Sig.Private Sig.RandomizePrivate:Sig.Random×Sig.PrivateSig.Private:为signing key randomization算法。
  • S i g . R a n d o m i z a P u b l i c : S i g . R a n d o m × S i g . P u b l i c → S i g . P u b l i c Sig.RandomizaPublic:Sig.Random\times Sig.Public\rightarrow Sig.Public Sig.RandomizaPublic:Sig.Random×Sig.PublicSig.Public:为validating key randomization算法。
  • O S i g . R a n d o m : S i g . R a n d o m \mathcal{O}_{Sig.Random}:Sig.Random OSig.Random:Sig.Random:为distinguished “identity” randomizer。

使得:

  • 对于任意的randomizer α : S i g . R a n d o m \alpha:Sig.Random α:Sig.Random,与 S i g . R a n d o m i z e P r i v a t e α : S i g . P r i v a t e → S i g . P r i v a t e Sig.RandomizePrivate_{\alpha}: Sig.Private\rightarrow Sig.Private Sig.RandomizePrivateα:Sig.PrivateSig.Private 为injective 且 容易进行逆运算的。
  • S i g . R a n d o m i z e P r i v a t e O S i g . R a n d o m Sig.RandomizePrivate_{\mathcal{O}_{Sig.Random}} Sig.RandomizePrivateOSig.Random S i g . P r i v a t e Sig.Private Sig.Private 的identity function。
  • 对于任意的 s k : S i g . P r i v a t e sk:Sig.Private sk:Sig.Private,其 S i g . R a n d o m i z e P r i v a t e ( α , s k ) : α ← R S i g . G e n R a n d o m ( ) Sig.RandomizePrivate(\alpha,sk):\alpha\leftarrow_R Sig.GenRandom() Sig.RandomizePrivate(α,sk):αRSig.GenRandom() 的分布 与 S i g . G e n t P r i v a t e ( ) Sig.GentPrivate() Sig.GentPrivate() 的分布相同。
  • 对于任意的 s k : S i g . P r i v a t e 和 α : S i g . R a n d o m sk:Sig.Private 和 \alpha:Sig.Random sk:Sig.Privateα:Sig.Random,有 S i g . R a n d o m i z e P u b l i c ( α , S i g . D e r i v e P u b l i c ( s k ) ) = S i g . D e r i v e P u b l i c ( S i g . R a n d o m i z e P r i v a t e ( α , s k ) ) Sig.RandomizePublic(\alpha,Sig.DerivePublic(sk))=Sig.DerivePublic(Sig.RandomizePrivate(\alpha,sk)) Sig.RandomizePublic(α,Sig.DerivePublic(sk))=Sig.DerivePublic(Sig.RandomizePrivate(α,sk)) 恒成立。

根据 FKMSSS2016-Efficient Unlinkable Sanitizable Signatures from Signatures with Re-Randomizable Keys 中section 3 Definition 8 “Unforgeability under Re-randomized Keys” 可知,此处的security requirement为:【数字签名伪造 Digital signature forgery

  • Strong Unforgeability with Re-randomized Keys 而不是 Existential Unforgeability with Re-randomized Keys
  • 与JoinSplitSig不同,要求 security under adaptive chosen message attack with multiple messages signed using a given key。【原因在于,尽管每个note都采用不同的re-randomized key pair,但是可能存在以下情况:1)使用了相同的original key pair 来 re-randomized for multiple note;2)adversary 获悉 多笔spending the same note 的交易。】

以上security requirement 统称为 SURK-CMA (Strong Unforgeability with Re-randomized Keys under adaptive Chosen Message Attack),具体内容为:
在这里插入图片描述
非规范性说明有:
在这里插入图片描述

4. 用于 BindingSig 的 Signature with Signing Key to Validating Key Monomorphism

【所谓Monomorphism,是指 injective homomorphism。】

具有 Key Monomorphism 的 signature scheme S i g Sig Sig 中 额外定义了:

  • 基于signing keys的abelian group,具有 ⊞ : S i g . P r i v a t e × S i g . P r i v a t e → S i g . P r i v a t e \boxplus: Sig.Private\times Sig.Private\rightarrow Sig.Private :Sig.Private×Sig.PrivateSig.Private操作 和 identity O ⊞ \mathcal{O}_{\boxplus} O
  • 基于validating keys的abelian group,具有 ⊕ : S i g . P u b l i c × S i g . P u b l i c → S i g . P u b l i c \oplus: Sig.Public\times Sig.Public\rightarrow Sig.Public :Sig.Public×Sig.PublicSig.Public操作 和 identity O ⊕ \mathcal{O}_{\oplus} O

满足:

  • 对于任意的 s k 1 , s k 2 : S i g . P r i v a t e sk_1,sk_2: Sig.Private sk1,sk2:Sig.Private,有 S i g . D e r i v e P u b l i c ( s k 1 ⊞ s k 2 ) = S i g . D e r i v e P u b l i c ( s k 1 ) ⊕ S i g . D e r i v e P u b l i c ( s k 2 ) Sig.DerivePublic(sk_1\boxplus sk_2)=Sig.DerivePublic(sk_1)\oplus Sig.DerivePublic(sk_2) Sig.DerivePublic(sk1sk2)=Sig.DerivePublic(sk1)Sig.DerivePublic(sk2) 成立。则可称 S i g . D e r i v e P u b l i c Sig.DerivePublic Sig.DerivePublic 为 monomorphism from the signing key group to the validating key group。

定义,对于 N : N + N:\mathbb{N}^+ N:N+,有:

  • ⊞ i = 1 N s k i = s k 1 ⊞ s k 2 ⊞ ⋯ s k N \boxplus_{i=1}^{N}sk_i=sk_1\boxplus sk_2\boxplus \cdots sk_{N} i=1Nski=sk1sk2skN
  • ⊕ i = 1 N v k i = v k 1 ⊕ v k 2 ⊕ ⋯ v k N \oplus_{i=1}^{N}vk_i=vk_1\oplus vk_2\oplus \cdots vk_{N} i=1Nvki=vk1vk2vkN

N = 0 N=0 N=0时,对应的为相应group 的identity,即 ⊞ i = 1 0 s k i = O ⊞ , ⊕ i = 1 0 v k i = O ⊕ \boxplus_{i=1}^{0}sk_i=\mathcal{O}_{\boxplus},\oplus_{i=1}^{0}vk_i=\mathcal{O}_{\oplus} i=10ski=O,i=10vki=O

同时具有:

  • signing key ⊟ s k \boxminus sk sk 满足 ( ⊟ s k ) ⊞ s k = O ⊞ (\boxminus sk)\boxplus sk =\mathcal{O}_{\boxplus} (sk)sk=O s k 1 ⊟ s k 2 = s k 1 ⊞ ( ⊟ s k 2 ) sk_1 \boxminus sk_2=sk_1 \boxplus (\boxminus sk_2) sk1sk2=sk1(sk2)
  • validating key ⊖ v k \ominus vk vk 满足 ( ⊖ v k ) ⊕ v k = O ⊕ (\ominus vk)\oplus vk =\mathcal{O}_{\oplus} (vk)vk=O v k 1 ⊖ v k 2 = v k 1 ⊕ ( ⊖ v k 2 ) vk_1 \ominus vk_2=vk_1 \oplus (\ominus vk_2) vk1vk2=vk1(vk2)

以上定义与 DS2016——Key-Homomorphic Signatures and Applications to Multiparty Signatures and Non-Interactive Zero-Knowledge 中的Definition 14类似,只是将其中的 μ \mu μ替换为 S i g . D e r i v e P u b l i c Sig.DerivePublic Sig.DerivePublic + + +替换为 ⊞ \boxplus ⋅ \cdot 替换为 ⊕ \oplus 。不同之处在于,此处额外要求 the homomorphism to be injective。

Security requirement为:
在这里插入图片描述

5. 生成 SpendAuthSig 的 Spend Authorization Signature (Sapling)

在Sapling中,使用 S p e n d A u t h S i g S a p l i n g SpendAuthSig^{Sapling} SpendAuthSigSapling来:

  • prove knowledge of the spending key authorizing spending of an input note。

Knowledge of the spending key 可直接在 Spend statement中进行证明,类似于Sprout的 JoinSplit Statement。

在Sapling中单独引入一个签名 S p e n d A u t h S i g S a p l i n g SpendAuthSig^{Sapling} SpendAuthSigSapling 的原因是:

  • 为了更好的支持具有 有限内存和有限算力 的设备——如hardware wallets,来authorize a Sapling shielded Spend。通常这些设备内存和算力无法创建,甚至无法验证,zk-SNARK proofs for a statement of the size needed using the BCTV14 or Groth16 proving systems。

S p e n d A u t h S i g S a p l i n g SpendAuthSig^{Sapling} SpendAuthSigSapling的validating key必须在Spend description中reveal,以使得validators可对该签名进行验签。
为了保证 validating key 不会 link to the shielded payment address or spending key from which the note was spent,要求使用a signature scheme with re-randomizable keys。

在Spend statement中,会证明:

  • S p e n d A u t h S i g S a p l i n g SpendAuthSig^{Sapling} SpendAuthSigSapling的validating key 为 a re-randomization of the spend authorization address key a k ak ak with a randomizer known to the signer。

为了防止跨交易重放, S p e n d A u t h S i g S a p l i n g SpendAuthSig^{Sapling} SpendAuthSigSapling 是对 SIGHASH transaction hash S i g H a s h SigHash SigHash 进行签名的。

a s k ask ask为the spend authorization private key。

对于每一个Spend description,signer会选择 fresh spend authorization randomizer α \alpha α,详细的 S p e n d A u t h S i g S a p l i n g SpendAuthSig^{Sapling} SpendAuthSigSapling 签名操作为:

  • 1)选择 α ← R S p e n d A u t h S i g S a p l i n g . G e n R a n d o m ( ) \alpha\leftarrow_R SpendAuthSig^{Sapling}.GenRandom() αRSpendAuthSigSapling.GenRandom()
  • 2)计算 r s k = S p e n d A u t h S i g S a p l i n g . R a n d o m i z e P r i v a t e ( α , a s k ) rsk=SpendAuthSig^{Sapling}.RandomizePrivate(\alpha,ask) rsk=SpendAuthSigSapling.RandomizePrivate(α,ask)
  • 3)计算 r k = S p e n d A u t h S i g S a p l i n g . D e r i v e P u b l i c ( r s k ) rk=SpendAuthSig^{Sapling}.DerivePublic(rsk) rk=SpendAuthSigSapling.DerivePublic(rsk)
  • 4)以 α \alpha α为auxiliary input, r k rk rk为primary input,为Spend statement构建proof π \pi π
  • 5)签名 s p e n d A u t h S i g = S p e n d A u t h S i g S a p l i n g . S i g n r s k ( S i g H a s h ) spendAuthSig=SpendAuthSig^{Sapling}.Sign_{rsk}(SigHash) spendAuthSig=SpendAuthSigSapling.Signrsk(SigHash)

最终 s p e n d A u t h S i g spendAuthSig spendAuthSig π \pi π以及 r k rk rk 都将包含在Spend description中。

注意:
若spender具有有限的算力或内存,可仅将上面的步骤4)delegate给有能力执行zk-SNARK proof的第三方。但是,此时需要给该第三方 a k ak ak n s k nsk nsk,将造成privacy lost。即拥有 a k ak ak n s k nsk nsk的第三方可识别该笔交易中的 spent notes,以及 recognize and decrypt incoming notes。但是该第三方无法obtain spending authority for other transactions,因为其无法自己创建 a spend authorization signature。

6. 生成 BindingSig 的 Balance and Binding Signature (Sapling)

Sprout中支持的交易类型有:

  • transparent transfer
  • JoinSplit transfer

Sapling在Sprout的基础之上,增加了以下交易类型:

  • Spend transfer
  • Output transfer

某笔交易中 所有Spend transfer的值 减去 所有Ouput transfer的值 称为 Sapling balancing value,以 zatoshi为单位,以有符号整数 v b a l a n c e S a p l i n g v^{balanceSapling} vbalanceSapling 表示。

v b a l a n c e S a p l i n g v^{balanceSapling} vbalanceSapling encode在交易的 valueBalanceSapling field中。

valueBalanceSapling 的取值范围为 { − M A X _ M O N E Y . . M A X _ M O N E Y } \{-MAX\_MONEY..MAX\_MONEY\} {MAX_MONEY..MAX_MONEY}

对于version 4 transaction,若其没有Sapling Spends或Outputs,则其 valueBalanceSapling 必须为0。

对于v4 transaction, v b a l a n c e S a p l i n g v^{balanceSapling} vbalanceSapling 总是explicitly encoded。
Zcash的每笔交易中包含2个value pool:

  • transparent transaction value pool
  • Sapling transaction value pool

v b a l a n c e S a p l i n g v^{balanceSapling} vbalanceSapling 为正值,是指 将value从 Sapling transaction value pool 中拿出,将其加到 transparent transaction value pool 中。 v b a l a n c e S a p l i n g v^{balanceSapling} vbalanceSapling 为正值,可看成是 an input to the transparent transaction value pool。

v b a l a n c e S a p l i n g v^{balanceSapling} vbalanceSapling 为负值,是指 将value从 transparent transaction value pool 中拿出,将其加到 Sapling transaction value pool 中。 v b a l a n c e S a p l i n g v^{balanceSapling} vbalanceSapling 为正值,可看成是 an output from the transparent transaction value pool。

根据 [ZIP-209] 中的定义,Zcash 中的Sapling chain value pool balance 为链上所有交易的所有valueBalanceSapling field值之和 的负值。【即 Sapling chain value pool balance 维护的是所有从 transparent transaction value pool 到 Sapling transaction value pool 中的差值,该差值应为非负数。】

若新增某区块,将使得Sapling chain value pool值成为负数,则所有节点都应reject该区块。

为了保证 the value commitments in Spend descriptions and Output descriptions 与 v b a l a n c e S a p l i n g v^{balanceSapling} vbalanceSapling 的一致性,Zcash中引入了 Sapling binding signature。
Sapling binding signature 在Zcash Sapling协议中承担双重角色:

  • 用于证明交易中 所有Spend transfers的value 减去 所有Output transfers的value 的差值,应与该交易中的 v b a l a n c e S a p l i n g v^{balanceSapling} vbalanceSapling field值一致。
  • 证明签名者知道用于Spend value commitments 和 Output value commitments中的随机值,防止adversary将Output descriptions replay到不同的交易中。而借助spend authorization signature,可防止Spend description replay。

交易binding signature中的signing key和validating key不是随机生成的key pair,而是基于交易中的value commitments in Spend descriptions、value commitments in Output descriptions以及Sapling balancing value 来计算的。

根据“Homomorphic Pedersen commitments (Sapling)”中的定义有:

  • V a l u e C o m m i t S a p l i n g : V a l u e C o m m i t S a p l i n g . T r a p d o o r × { − r J − 1 2 , r J − 1 2 } → V a l u e C o m m i t S a p l i n g . O u t p u t ValueCommit^{Sapling}:ValueCommit^{Sapling}.Trapdoor\times \{-\frac{r_{\mathbb{J}-1}}{2}, \frac{r_{\mathbb{J}-1}}{2}\}\rightarrow ValueCommit^{Sapling}.Output ValueCommitSapling:ValueCommitSapling.Trapdoor×{2rJ1,2rJ1}ValueCommitSapling.Output。基于Jubjub curve的实现为: V a l u e C o m m i t r c v ( v ) = H o m o m o r p h i c P e d e r s e n C o m m i t r c v S a p l i n g ( " Z c a s h _ c v " , v ) = [ v ] F i n d G r o u p H a s h J ( r ) ∗ ( " Z c a s h _ c v " , " v " ) + [ r c v ] F i n d G r o u p H a s h J ( r ) ∗ ( " Z c a s h _ c v " , " r " ) = [ v ] V S a p l i n g + [ r c v ] R S a p l i n g ValueCommit^{rcv}(v)=HomomorphicPedersenCommit_{rcv}^{Sapling}("Zcash\_cv", v)=[v]FindGroupHash^{\mathbb{J}^{(r)*}}("Zcash\_cv", "v")+[rcv]FindGroupHash^{\mathbb{J}^{(r)*}}("Zcash\_cv", "r")=[v]\mathcal{V}^{Sapling}+[rcv]\mathcal{R}^{Sapling} ValueCommitrcv(v)=HomomorphicPedersenCommitrcvSapling("Zcash_cv",v)=[v]FindGroupHashJ(r)("Zcash_cv","v")+[rcv]FindGroupHashJ(r)("Zcash_cv","r")=[v]VSapling+[rcv]RSapling
  • V S a p l i n g : J ( r ) ∗ \mathcal{V}^{Sapling}:\mathbb{J}^{(r)^*} VSapling:J(r):为 V a l u e C o m m i t S a p l i n g ValueCommit^{Sapling} ValueCommitSapling 的 value base。基于Jubjub curve实现为: V S a p l i n g = F i n d G r o u p H a s h J ( r ) ∗ ( " Z c a s h _ c v " , " v " ) \mathcal{V}^{Sapling}=FindGroupHash^{\mathbb{J}^{(r)*}}("Zcash\_cv", "v") VSapling=FindGroupHashJ(r)("Zcash_cv","v")
  • R S a p l i n g : J ( r ) ∗ \mathcal{R}^{Sapling}:\mathbb{J}^{(r)^*} RSapling:J(r):为 V a l u e C o m m i t S a p l i n g ValueCommit^{Sapling} ValueCommitSapling 的 randomness base。基于Jubjub curve实现为: R S a p l i n g = F i n d G r o u p H a s h J ( r ) ∗ ( " Z c a s h _ c v " , " " ) \mathcal{R}^{Sapling}=FindGroupHash^{\mathbb{J}^{(r)*}}("Zcash\_cv", "") RSapling=FindGroupHashJ(r)("Zcash_cv","")

第4节 “用于 BindingSig 的 Signature with Signing Key to Validating Key Monomorphism” 中的 ⊖ , ⊕ i = 1 N , ⊟ , ⊞ i = 1 N \ominus,\oplus_{i=1}^{N},\boxminus,\boxplus_{i=1}^{N} ,i=1N,,i=1N 都是基于 prime-order subgroup of the Jubjub curve and its scalar field 进行的。

假设交易中包含:

  • n n n个Spend descriptions with value commitments c v 1.. n o l d cv_{1..n}^{old} cv1..nold committing to values v 1.. n o l d v_{1..n}^{old} v1..nold with randomness r c v 1.. n o l d rcv_{1..n}^{old} rcv1..nold
  • m m m个Output descriptions with value commitments c v 1.. m n e w cv_{1..m}^{new} cv1..mnew committing to values v 1.. m n e w v_{1..m}^{new} v1..mnew with randomness r c v 1.. m n e w rcv_{1..m}^{new} rcv1..mnew
  • Sapling balancing value v b a l a n c e S a p l i n g v^{balanceSapling} vbalanceSapling

在正确构建的交易中,有 v b a l a n c e S a p l i n g = ∑ i = 1 n v i o l d − ∑ j = 1 m v j n e w v^{balanceSapling} = \sum_{i=1}^{n}v_i^{old}-\sum_{j=1}^{m}v_j^{new} vbalanceSapling=i=1nvioldj=1mvjnew。但是validators无法直接进行验证,因为 c v 1.. n o l d cv_{1..n}^{old} cv1..nold c v 1.. m n e w cv_{1..m}^{new} cv1..mnew 都被commitments hide了。

validators可按如下方式计算the transaction binding validating key:【该key值不许explicitly encode在交易中,仅要求可按如下公式计算即可。】
b v k S a p l i n g = ( ⊕ i = 1 n c v i o l d ) ⊖ ( ⊕ j = 1 m c v i n e w ) ⊖ V a l u e C o m m i t 0 S a p l i n g ( v b a l a n c e S a p l i n g ) bvk^{Sapling}=(\oplus_{i=1}^{n}cv_i^{old})\ominus (\oplus_{j=1}^{m}cv_i^{new})\ominus ValueCommit_0^{Sapling}(v^{balanceSapling}) bvkSapling=(i=1ncviold)(j=1mcvinew)ValueCommit0Sapling(vbalanceSapling)

signer知道 r c v 1.. n o l d rcv_{1..n}^{old} rcv1..nold r c v 1.. m n e w rcv_{1..m}^{new} rcv1..mnew,因此可按如下方式计算相应的signing key:
b s k S a p l i n g = ( ⊞ i = 1 n r c v i o l d ) ⊟ ( ⊞ j = 1 m r c v j n e w ) ) bsk^{Sapling}=(\boxplus_{i=1}^{n}rcv_i^{old})\boxminus (\boxplus_{j=1}^{m}rcv_j^{new})) bskSapling=(i=1nrcviold)(j=1mrcvjnew))

为了验证以上用于 binding signature 的 signing key 和 validating key是否是正确的key pair,可判断:
b v k S a p l i n g = B i n d i n g S i g S a p l i n g . D e r i v e P u b l i c ( b s k S a p l i n g ) bvk^{Sapling}=BindingSig^{Sapling}.DerivePublic(bsk^{Sapling}) bvkSapling=BindingSigSapling.DerivePublic(bskSapling)
成立即可。

S i g H a s h SigHash SigHash 为 Sapling中的 SIGHASH transaction hash [ZIP-243] —— for a version 4 transaction。

则validator可通过验证以下签名来check balance:
B i n d i n g S i g S a p l i n g . V a l i d a t e b v k S a p l i n g ( S i g H a s h , b i n d i n g S i g S a p l i n g ) = 1 BindingSig^{Sapling}.Validate_{bvk^{Sapling}}(SigHash, bindingSigSapling) = 1 BindingSigSapling.ValidatebvkSapling(SigHash,bindingSigSapling)=1

6.1 binding signature可check balance的原理

Sapling binding signature 可:

  • prove knowledge of the discrete logarithm b s k S a p l i n g bsk^{Sapling} bskSapling of b v k S a p l i n g bvk^{Sapling} bvkSapling with respect to R S a p l i n g \mathcal{R}^{Sapling} RSapling,即 b v k S a p l i n g = [ b s k S a p l i n g ] R S a p l i n g bvk^{Sapling}=[bsk^{Sapling}]\mathcal{R}^{Sapling} bvkSapling=[bskSapling]RSapling

可将其看成是 value 0 0 0 和 randomness b s k S a p l i n g bsk^{Sapling} bskSapling 的commitment,即:
b v k S a p l i n g = V a l u e C o m m i t b s k S a p l i n g S a p l i n g ( 0 ) bvk^{Sapling}=ValueCommit_{bsk^{Sapling}}^{Sapling}(0) bvkSapling=ValueCommitbskSaplingSapling(0)

根据Pedersen commitment的binding属性,即不可能将一个commitment open为2个不同的值。

类似的,Spend descriptions和Output descriptions中的value commitments也具有binding属性,adversary无法将这些commitments open出不同的值,即 c v 1.. n o l d cv_{1..n}^{old} cv1..nold可确定 v 1.. n o l d v_{1..n}^{old} v1..nold c v 1.. n e w cv_{1..}^{new} cv1..new可确定 v 1.. m n e w v_{1..m}^{new} v1..mnew

同时,根据Groth16的Knowledge Soundness假设,有:

  • 无法在不知道 r c v 1.. n o l d ( m o d    r J ) rcv_{1..n}^{old}(\mod r_{\mathbb{J}}) rcv1..nold(modrJ)的情况下生成有效的Spend proofs。
  • 无法在不知道 r c v 1.. m n e w ( m o d    r J ) rcv_{1..m}^{new}(\mod r_{\mathbb{J}}) rcv1..mnew(modrJ)的情况下生成有效的Output proofs。

从以下两个维度进行了证明:

  • 1)归谬法基于Pedersen commitment binding属性证明 b v k S a p l i n g = V a l u e C o m m i t b s k S a p l i n g S a p l i n g ( 0 ) bvk^{Sapling}=ValueCommit_{bsk^{Sapling}}^{Sapling}(0) bvkSapling=ValueCommitbskSaplingSapling(0)
  • 2)对于 ( m o d    r J ) (\mod r_{\mathbb{J}}) (modrJ)运算,证明value在 { − r J − 1 2 , r J − 1 2 } \{-\frac{r_{\mathbb{J}-1}}{2}, \frac{r_{\mathbb{J}-1}}{2}\} {2rJ1,2rJ1} 区间未溢出。

在这里插入图片描述
注意:
Spender可能会将以上value commitment randomnesses的一部分reveal给创建交易的合作方,当所有value commitment randomnesses都reveal了的话,则可能会允许对该笔交易内的Output descriptions进行replay。

类似地基于Perdersen commitments运算来获取验签的validating key的方法,在 Mimblewimble 协议 和 Bulletproofs 中也有使用:

  • private key b s k S a p l i n g bsk^{Sapling} bskSapling 作为”synthetic blinding factor“,是基于 blinding factors (trapdoors) r c v 1.. n o l d rcv_{1..n}^{old} rcv1..nold r c v 1.. m n e w rcv_{1..m}^{new} rcv1..mnew 合成的。

7. RedDSA and RedJubjub

RedDSA 为Schnorr-based signature scheme,可支持:

  • S p e n d A u t h S i g SpendAuthSig SpendAuthSig 所需的key re-randomization; 【generator为 P S a p l i n g = G S a p l i n g = F i n d G r o u p H a s h J ( r ) ∗ ( " Z c a s h _ G _ " , " " ) \mathcal{P}^{Sapling}=\mathcal{G}^{Sapling}=FindGroupHash^{\mathbb{J}^{(r)*}}("Zcash\_G\_","") PSapling=GSapling=FindGroupHashJ(r)("Zcash_G_","")。】
  • B i n d i n g S i g BindingSig BindingSig 所需的 Secret Key to Public Key Monomorphism。【generator为 P S a p l i n g = R S a p l i n g = F i n d G r o u p H a s h J ( r ) ∗ ( " Z c a s h _ c v " , " " ) \mathcal{P}^{Sapling}=\mathcal{R}^{Sapling}=FindGroupHash^{\mathbb{J}^{(r)*}}("Zcash\_cv", "") PSapling=RSapling=FindGroupHashJ(r)("Zcash_cv","")。】

RedDSA签名机制主要基于 FKMSSS2016-Efficient Unlinkable Sanitizable Signatures from Signatures with Re-Randomizable Keys 中section 3 ,同时借鉴了EdDSA中的一些思想。

RedJubjub 是指:
基于Jubjub curve 的RedDSA实现,使用了BLAKE2b-512 hash 函数。

最终的RedJubjub签名结果为 ( R , S ) (R,S) (R,S)

参考资料

[1] Zcash Protocol Specification
[2] 数字签名伪造 Digital signature forgery

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值