Zcash中的keys和addresses

1. 引言

【还有个 o c k ock ock:outgoing cipher key,用于encrypt an outgoing ciphertext。】

在Zcash协议中,用户若想接收shielded payments,则其必须拥有a shielded payment address,该shielded payment address 可由 a spending key 生成。

相比于Sprout,Sapling中增加了更多的key类型。下图中的箭头指向表示了key之间的衍生关系;双线型表示的相同的key,只是做了不同的抽象。
在这里插入图片描述

在Sprout中,有:

  • receiving key s k e n c sk_{enc} skenc
  • incoming viewing key i v k = ( a p k , s k e n c ) ivk=(a_{pk}, sk_{enc}) ivk=(apk,skenc)
  • shielded payment address a d d r p k = ( a p k , p k e n c ) addr_{pk}=(a_{pk},pk_{enc}) addrpk=(apk,pkenc)

Sprout中的这些key都衍生自spending key a s k a_{sk} ask

下图摘自博客 Zcash - 各种密钥和签名,你懂吗?
在这里插入图片描述

在Sapling中,有:

  • Spending key s k sk sk,为256bit的random值。

  • Expanded spending key ( a s k , n s k , o v k ) (ask, nsk, ovk) (ask,nsk,ovk),其中 a s k ask ask为Spend authorizing key, n s k nsk nsk为nullifier private key, o v k ovk ovk为outgoing viewing key。 a s k , n s k ask,nsk ask,nsk均为scalar field值, o v k ovk ovk为32byte值。
    在这里插入图片描述

  • Proof authorizing key ( a k , n s k ) (ak, nsk) (ak,nsk),其中 a k ak ak为Jubjub Point,与 a s k ask ask的关系为 a k = a s k   ∗  Jubjub.SpendingKeyGenerator ak=ask\ *\ \text{Jubjub.SpendingKeyGenerator} ak=ask  Jubjub.SpendingKeyGenerator

let ak = fixed_scalar_mult(ask, FixedGenerators::SpendingKeyGenerator);
  • Full viewing key ( a k , n k , o v k ) (ak,nk,ovk) (ak,nk,ovk),其中 n k nk nk为Jubjub Point,与 n s k nsk nsk的关系为 n k = n s k   ∗  Jubjub.ProofGenerationKey nk=nsk\ *\ \text{Jubjub.ProofGenerationKey} nk=nsk  Jubjub.ProofGenerationKey
let nk = fixed_scalar_mult(nsk, FixedGenerators::ProofGenerationKey);
  • Incoming viewing key i v k ivk ivk,取值范围为 [ 1 , 2 251 − 1 ] [1,2^{251}-1] [1,22511],根据 a k , n k ak,nk ak,nk计算获得。
#[no_mangle]
pub extern "system" fn librustzcash_crh_ivk(
    ak: *const [c_uchar; 32],
    nk: *const [c_uchar; 32],
    result: *mut [c_uchar; 32],
) {
    let ak = unsafe { &*ak };
    let nk = unsafe { &*nk };

    let mut h = Blake2s::with_params(32, &[], &[], CRH_IVK_PERSONALIZATION);
    h.update(ak);
    h.update(nk);
    let mut h = h.finalize().as_ref().to_vec();

    // Drop the last five bits, so it can be interpreted as a scalar.
    h[31] &= 0b0000_0111;

    let result = unsafe { &mut *result };

    result.copy_from_slice(&h);
}

在这里插入图片描述

  • diversified shielded payment address a d d r d = ( d , p k d ) addr_d=(d,pk_d) addrd=(d,pkd)(由Diversifier d d d和 Transmission key p k d pk_d pkd组成)。diversifier d d d为88bit随机值,要求存在与 d d d对应的diversified base g d = D i v e r s i f y H a s h S a p l i n g ( d ) g_d = DiversifyHash^{Sapling}(d) gd=DiversifyHashSapling(d)。【可借助encodePaymentAddress()函数,将 d , p k d d,pk_d d,pkd组合成一串单一的shielded payment address。】
#[no_mangle]
pub extern "system" fn librustzcash_check_diversifier(diversifier: *const [c_uchar; 11]) -> bool {
    let diversifier = sapling_crypto::primitives::Diversifier(unsafe { *diversifier });
    diversifier.g_d::<Bls12>(&JUBJUB).is_some()
}

根据 i v k ivk ivk d d d 可生成相应的diversified transmission key p k d pk_d pkd p k d pk_d pkd为Jubjub point。
在这里插入图片描述
在这里插入图片描述

#[no_mangle]
pub extern "system" fn librustzcash_ivk_to_pkd(
    ivk: *const [c_uchar; 32],
    diversifier: *const [c_uchar; 11],
    result: *mut [c_uchar; 32],
) -> bool {
    let ivk = read_fs(unsafe { &*ivk });
    let diversifier = sapling_crypto::primitives::Diversifier(unsafe { *diversifier }); //此处即为Diversify Hash函数。
    if let Some(g_d) = diversifier.g_d::<Bls12>(&JUBJUB) { 
        let pk_d = g_d.mul(ivk, &JUBJUB);

        let result = unsafe { &mut *result };

        pk_d.write(&mut result[..]).expect("length is 32 bytes");

        true
    } else {
        false
    }
}

对于每个spending key,对应有a default diversified payment address with a “random-looking” diversifier。若无法区分default address和以上通过random diversifier生成的地址,则可实现不暴露diversified addresses as a user-visible feature。但是实际zcashd wallet中并未使用default diversified payment address,而是采用ZIP-32 中的方案来生成
注意,整个协议中使用Bech32.encode()是可能产生vanity address的,从而可能会存在泄漏隐私的问题。软件开发者在实际实现时要注意使用randomly chosen diversifier,同时也建议 diversifiers be randomly chosen unique values used to index into a database, rather than directly encoding the needed data。

Zcash的共识协议不依赖于expanded spending key的构建方式。expanded spending key的构建方式有以下两种:

  1. 随机生成spending key s k sk sk,基于 s k sk sk生成expanded spending key ( a s k , n s k , o v k ) (ask,nsk,ovk) (ask,nsk,ovk)
  2. 根据 ZIP-32,其中包含了expanded spending key的superset。该方式已用于Hierarchical Deterministic Wallet中。但是目前Zcash还不支持Hierarchical Deterministic Wallet address。

在zcashd(Zcash的官方客户端软件)中,所有的Sapling keys和addresses都是根据 ZIP-32生成的。

Sapling中的shielded payment addresses、incoming viewing keys、full viewing keys和spending keys均为a cryptographic protocol detail,这些信息正常来说不应直接暴露给用户。但是,user-visible operations需要知悉shielded payment address、incoming viewing key、(或)来自于spending key或extended spending key的full viewing key。
【在Sapling中,对于每一个spending key,其对应的full viewing key可在无spend authority的情况下,识别出incoming和outgoing notes。具体的解决方案为在每个Output description中增加额外的ciphertext。】

用户可 以一个shielded payment address 来接收来自 多方的支付,事实上,这些支付指向的是同一收款人 这一信息并不会暴露在区块链上,即使是对支付方来说,也无法知悉这些支付指向的是同一收款人。但是,若两个支付方勾结比对了收款方对应的shielded payment address,则可完全确定指向的是同一收款人。为了避免这种情况,收款方可为每个支付方创建不同的shielded payment address。

在Sapling中,提供了一种为同一spending authority 高效生成diversified payment addresses的机制,这些diversified payment addresses共享相同的full viewing key和incoming viewing key。创建大量这样的diversified payment addresses并不会给 扫描区块链以获取相关交易 增加额外开销。

密码学传统上将非对称加密中用于加密的key称为“public key”。transmission key中作为public key的为 p k e n c pk_{enc} pkenc p k d pk_d pkd。这个public key不需要单独分发,因为其已包含在shielded payment address中。

同时注意,控制shielded payment address的分发在某些应用场景下是必要的。同时,这也有助于减少整个协议对 note encryption中使用的密码学安全性的依赖。【具体可参见Zcash Protocol Specification 4.17节“In-band secret distribution (Sapling)”中的分析,知道某些 p k d pk_{d} pkd的攻击者可尝试寻找整个密码学系统中的某些假设薄弱点。】

2. Sapling Key Components

Sapling中,有:

  • l P R F e x p a n d 为 N = 512 , l s k 为 256 , l i v k S a p l i n g 为 251 , l o v k 为 256 , l d 为 88 l_{PRFexpand}为\mathbb{N}=512, l_{sk}为256, l_{ivk}^{Sapling}为251, l_{ovk}为256, l_{d}为88 lPRFexpandN=512,lsk256,livkSapling251,lovk256,ld88 均为常量。
  • J ( r ) , J ( r ) ∗ , J ∗ ( r ) , r e p r J , r J \mathbb{J}^{(r)},\mathbb{J}^{(r)*},\mathbb{J}_{*}^{(r)},repr_{\mathbb{J}},r_{\mathbb{J}} J(r),J(r),J(r),reprJ,rJ 均为Jubjub相关参数,其中:
    J ( r ) \mathbb{J}^{(r)} J(r)为order- r J r_{\mathbb{J}} rJ subgroup of J \mathbb{J} J。该subgroup中包含了 O J \mathcal{O}_{\mathbb{J}} OJ。除 O J \mathcal{O}_{\mathbb{J}} OJ之外的,order 为 r J r_{\mathbb{J}} rJ的point set表示为 J ( r ) ∗ \mathbb{J}^{(r)*} J(r)
  • F i n d G r o u p H a s h J ( r ) ∗ FindGroupHash^{\mathbb{J}^{(r)*}} FindGroupHashJ(r)为“Group Hash into Jubjub”。返回无效point的概率接近 2 − 256 2^{-256} 2256
  • P R F e x p a n d 和 P R F o c k S a p l i n g PRF^{expand}和PRF^{ockSapling} PRFexpandPRFockSapling为Pseudo Random Functions。
  • K A S a p l i n g KA^{Sapling} KASapling为Sapling Key Agreement。
  • C R H i v k CRH^{ivk} CRHivk C R H i v k CRH^{ivk} CRHivk Hash Function。
  • D i v e r s i f y H a s h S a p l i n g DiversifyHash^{Sapling} DiversifyHashSapling D i v e r s i f y H a s h S a p l i n g DiversifyHash^{Sapling} DiversifyHashSapling Hash Function。
  • S p e n d A u t h S i g S a p l i n g SpendAuthSig^{Sapling} SpendAuthSigSapling Spend Authorization Signature (Sapling),为a signature scheme with re-randomizable keys。
  • LEBS2OSP为 ( l : N ) × B [ l ] − > B Y [ c e i l i n g ( l / 8 ) ] (l:\mathbb{N})\times\mathbb{B}^{[l]}->\mathbb{B}^{\mathbb{Y}^{[ceiling(l/8)]}} (l:N)×B[l]>BY[ceiling(l/8)]
    LEOS2IP为 ( l : N ∣ l m o d    8 = 0 ) × B B Y [ l / 8 ] − > { 0 ⋯ 2 l − 1 } (l:\mathbb{N}|l\mod 8 = 0)\times\mathbb{B}^{\mathbb{B}^{\mathbb{Y}^{[l/8]}}}->\{0\cdots 2^l-1\} (l:Nlmod8=0)×BBY[l/8]>{02l1}
    LEBS2OSP和LEOS2IP为“Integers, Bit Sequenes, and Endianness”中相关定义。

3. Sapling Payment Addresses

Sapling 的shielded payment address 为 a d d r d = ( d , p k d ) addr_d=(d,pk_d) addrd=(d,pkd)(由88-bit Diversifier d d d和 256-bit Transmission key p k d pk_d pkd组成)。其raw encoding规则分别为:

  • L E B S 2 O S P 88 ( d ) LEBS2OSP_{88}(d) LEBS2OSP88(d)
  • L E B S 2 O S P 256 ( r e p r J ( p k d ) ) LEBS2OSP_{256}(repr_{\mathbb{J}}(pk_d)) LEBS2OSP256(reprJ(pkd))

encoding以后再加上某些Human-Readable前缀,如Zcash主网上的shielded payment address以“zs”打头,而Zcash测试网上的shielded payment address则以“ztestsapling”打头。
在这里插入图片描述

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。

4. Sapling Incoming Viewing Keys

Sapling中的 i v k ivk ivk取值范围为 [ 1 , 2 251 − 1 ] [1,2^{251}-1] [1,22511],实际实现以256-bit表示,其中最高的5个-bit会做置零操作。
Zcash主网上的incoming viewing key前缀为“zivks”,测试网的incoming viewing key前缀为“zivktestsapling”。
在这里插入图片描述

5. Sapling Full Viewing Keys

Full viewing key ( a k , n k , o v k ) (ak,nk,ovk) (ak,nk,ovk),其中 a k , n k ak,nk ak,nk为Jubjub point,outgoing viewing key o v k ovk ovk 为32byte值。可将其编码为一个单独的串,编码规则为:

  • L E B S 2 O S P 256 ( r e p r J ( a k ) ) LEBS2OSP_{256}(repr_{\mathbb{J}}(ak)) LEBS2OSP256(reprJ(ak))
  • L E B S 2 O S P 256 ( r e p r J ( n k ) ) LEBS2OSP_{256}(repr_{\mathbb{J}}(nk)) LEBS2OSP256(reprJ(nk))
  • 32-byte o v k ovk ovk

在Zcash主网中,full viewing key前缀为“zviews”,测试网的前缀为“zviewtestsapling”。
在这里插入图片描述

在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中的加解密机制

6. Sapling Spending Keys

Sapling中的spending key 以256-bit表示。
Zcash主网中的spending key前缀为“secret-spending-key-main”,测试网的前缀为“secret-spending-key-test”。

Spending key为私钥的一种,拥有spending key的用户可spend the balance of the associated address。对于shielded address,拥有相应spending key的用户可查看address’ balance and transaction data。
在这里插入图片描述

参考资料

[1] Zcash Protocol Specification
[2] 博客 Zcash - 各种密钥和签名,你懂吗?
[3] Zcash Protocol Specification
Version 2021.1.22 [NU5 proposal]

[4] Zcash官方文档

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值