Schnorr签名 vs. EdDSA

1. 引言

前序博客:

所谓Schnorr签名,是指:

  • 签名:将消息 m m m 签署为: σ = ( R , s ) \sigma = (R, s) σ=(R,s),其中:
    • r ← § Z p r\xleftarrow{\S} \mathbb{Z}_p r§ Zp为随机值
    • R = g r R = g^r R=gr
    • s = r − H ( R , m ) ⋅ s k s = r - H(R, m) \cdot sk s=rH(R,m)sk
  • 验签:基于公钥 p k = g s k pk = g^{sk} pk=gsk,若 R = g s ⋅ p k H ( R , m ) R = g^s \cdot pk^{H(R, m)} R=gspkH(R,m)成立,则验签通过。

2. Schnorr签名历史

Schnorr签名方案由德国数学家Claus-Peter Schnorr在 CRYPTO 1989论文Efficient Identification and Signatures for Smart Cards中首次提出,在该论文中:

  • Claus-Peter Schnorr提出了一种identification身份证明方案,并通过使用著名的Fiat-Shamir transform转换为签名方案。关于Fiat-Shamir transform,详情见Amos Fiat和Adi Shamir CRYPTO 1986论文How To Prove Yourself: Practical Solutions to Identification and Signature Problems
  • 该签名方案所选择的Abelian group为: Z p ∗ \mathbb{Z}_p^* Zp的prime-order q q q子群,其中 p p p为素数。
    • 后续的研究成果发现可扩展为任意prime-order group——如椭圆曲线群。

Claus-Peter Schnorr在1990为其方案申请了专利。

  • 这可能是比特币和其他加密货币领域选择ECDSA而不是Schnorr作为其签名方案的最大原因。
  • Schnorr更简单、更高效、更容易做t-of-n门限签名。
  • 2010年,专利到期后,Schnorr签名变得更受欢迎。

相比于Schnorr签名,ECDSA签名方案的最大优势在于其public key recovery公钥恢复特性——Bitcoin P2PKH模式下利用了该特性,来让TXN签名更小。实际上,自比特币创立以来,其即使用了P2PKH模式

3. Schnorr签名方案——prime-order group

预备知识:

  • 有prime order p p p 的group G \mathbb{G} G 和有限域 Z p \mathbb{Z}_p Zp
  • g g g G \mathbb{G} G的generator
  • 抗碰撞哈希函数 H : G × { 0 , 1 } ∗ → Z p H : \mathbb{G} \times \{0,1\}^* \rightarrow \mathbb{Z}_p H:G×{0,1}Zp

S c h n o r r \mathsf{Schnorr} Schnorr. K e y G e n ( 1 λ ) → ( s k , p k ) \mathsf{KeyGen}(1^\lambda) \rightarrow (sk, pk) KeyGen(1λ)(sk,pk):

  • s k ← § Z p sk\xleftarrow{\S}\mathbb{Z}_p sk§ Zp
  • p k ← g s k pk \gets g^{sk} pkgsk

S c h n o r r \mathsf{Schnorr} Schnorr. S i g n ( m , s k ) → σ \mathsf{Sign}(m, sk) \rightarrow \sigma Sign(m,sk)σ:

  • r ← § Z p r\xleftarrow{\S}\mathbb{Z}_p r§ Zp
  • R ← g r R \gets g^r Rgr
  • s ← ( r − H ( R , m ) ⋅ s k )   m o d   p s \gets (r - H(R, m) \cdot sk) \bmod p s(rH(R,m)sk)modp 【注意也可用加号来代替其中的减号,验签时做相应调整即可。】
  • σ ← ( R , s ) \sigma\gets (R, s) σ(R,s)

S c h n o r r \mathsf{Schnorr} Schnorr. V e r i f y ( m , p k , σ ) → { 0 , 1 } \mathsf{Verify}(m, pk, \sigma) \rightarrow \{0,1\} Verify(m,pk,σ){0,1}:

  • ( R , s ) ← σ (R, s) \gets \sigma (R,s)σ
  • assert R = ? g s ⋅ p k H ( R , m ) R \overset{\text{?}}{=} g^s \cdot pk^{H(R, m)} R=?gspkH(R,m)

3.1 Schnorr签名方案正确性

若由 S c h n o r r . S i g n \mathsf{Schnorr.Sign} Schnorr.Sign创建的签名,可通过 S c h n o r r . V e r i f y \mathsf{Schnorr.Verify} Schnorr.Verify验证正确,则该签名方案具备correctness正确性:
R = ? g s ⋅ p k H ( R , m ) g r = ? g r − H ( R , m ) ⋅ s k ⋅ ( g s k ) H ( R , m ) g r = ? g r − H ( R , m ) ⋅ s k ⋅ g H ( R , m ) ⋅ s k g r = ? g r \begin{align} R &\overset{\text{?}}{=} g^s \cdot pk^{H(R, m)}\\ g^r &\overset{\text{?}}{=} g^{r-H(R, m)\cdot sk} \cdot (g^{sk})^{H(R, m)}\\ g^r &\overset{\text{?}}{=} g^{r-H(R, m)\cdot sk} \cdot g^{H(R, m) \cdot sk}\\ g^r &\overset{\text{?}}{=} g^r \end{align} Rgrgrgr=?gspkH(R,m)=?grH(R,m)sk(gsk)H(R,m)=?grH(R,m)skgH(R,m)sk=?gr

3.2 Schnorr签名 σ = ( R , s ) \sigma=(R,s) σ=(R,s)批量验证

批量验证Schnorr签名,要比逐个验证,快得多。
如对于 n n n个签名 ( σ i , m i , p k i ) i ∈ [ n ] (\sigma_i, m_i, pk_i)_{i\in [n]} (σi,mi,pki)i[n],其中 σ i = ( R i , s i ) \sigma_i = (R_i, s_i) σi=(Ri,si),可通过将 S c h n o r r . V e r i f y ( m i , p k i , σ i ) = 1 , ∀ i ∈ [ n ] \mathsf{Schnorr.Verify}(m_i, pk_i, \sigma_i) = 1,\forall i\in [n] Schnorr.Verify(mi,pki,σi)=1,i[n]的所有验签方程式线性随机组合为一个验签方程式,来一次验证所有签名,即所谓的批量验证算法 S c h n o r r . B a t c h V e r i f y ( ( m i , p k i , σ i ) i ∈ [ n ] ) → { 0 , 1 } \mathsf{Schnorr.BatchVerify}((m_i, pk_i, \sigma_i)_{i\in[n]}) \rightarrow \{0,1\} Schnorr.BatchVerify((mi,pki,σi)i[n]){0,1}为:

  • z _ i ← § { 0 , 1 } λ , ∀ i ∈ [ n ] z\_i \xleftarrow{\S} \{0,1\}^\lambda,\forall i\in[n] z_i§ {0,1}λ,i[n]
  • ( R i , s i ) ← σ i , ∀ i ∈ [ n ] (R_i,s_i)\gets \sigma_i, \forall i \in [n] (Ri,si)σi,i[n]
  • assert ∏ i ∈ [ n ] R i − z i g s _ i ⋅ z i p k i H ( R i , m i ) ⋅ z i = ? 1 \prod_{i \in [n]} R_i^{-z_i} g^{s\_i \cdot z_i} pk_i^{H(R_i, m_i)\cdot z_i}\overset{\text{?}}{=} 1 i[n]Rizigs_izipkiH(Ri,mi)zi=?1

其中assert 方程式中的multi-exponentiation计算,可使用如Bos-Coster或BDL+12算法来加速。BDL+12算法见2012年论文《High-speed high-security signatures》。

当所需批量验证的签名都源自同一公钥时,即 p k i = p k , ∀ i ∈ [ n ] pk_i = pk, \forall i\in[n] pki=pk,i[n],可进一步降低multi-exponentiation size,实现加速:
( ∏ i ∈ [ n ] R i − z i g s i ⋅ z i ) p k ∑ i ∈ [ n ] H ( R i , m i ) ⋅ z i = ? 1 \begin{align} \left(\prod_{i \in [n]} R_i^{-z_i} g^{s_i \cdot z_i}\right) pk^{\sum_{i\in[n]} H(R_i, m_i)\cdot z_i} \overset{\text{?}}{=} 1 \end{align} i[n]Rizigsizi pki[n]H(Ri,mi)zi=?1

基于prime order group实现Schnorr签名批量验证,使其返回与单个验证相同的结果。而若是基于non-prime order group(Edwards 25519)上做签名的批量验证,则要更棘手。

3.3 Schnorr签名的另一种表示—— σ ′ = ( e , s ) \sigma'=(e, s) σ=(e,s)

将Schnorr签名,由 σ = ( R , s ) \sigma=(R,s) σ=(R,s),转换为另一种表示: σ ′ = ( e , s ) \sigma'=(e, s) σ=(e,s),其中 e = H ( R , m ) e = H(R, m) e=H(R,m)

  • 这样做的可能优势在于:哈希函数 H H H可让 e e e R R R所需的bit数更少。
  • 劣势在于:不支持更高效的批量验签。

S c h n o r r ′ \mathsf{Schnorr}' Schnorr. S i g n ( m , s k ) → σ \mathsf{Sign}(m, sk) \rightarrow \sigma Sign(m,sk)σ:

  • r ← § Z p r\xleftarrow{\S}\mathbb{Z}_p r§ Zp
  • R ← g r R \gets g^r Rgr
  • e ← H ( R , m ) e \gets H(R, m) eH(R,m)
  • s ← ( r + e ⋅ s k )   m o d   p s \gets (r + e \cdot sk)\bmod p s(r+esk)modp
  • σ ← ( e , s ) \sigma\gets (e, s) σ(e,s)

S c h n o r r ′ \mathsf{Schnorr}' Schnorr. V e r i f y ( m , p k , σ ) → { 0 , 1 } \mathsf{Verify}(m, pk, \sigma) \rightarrow \{0,1\} Verify(m,pk,σ){0,1}:

  • ( e , s ) ← σ (e, s) \gets \sigma (e,s)σ
  • assert e = ? H ( g s ⋅ p k e , m ) e \overset{\text{?}}{=} H(g^s \cdot pk^e, m) e=?H(gspke,m)

4. EdDSA 和 Ed25519——non-prime order group

4.1 EdDSA签名方案——针对non-prime order group基于Schnorr的签名方案

EdDSA为:

  • 基于Schnorr的签名方案
  • 针对non-prime order p = h ⋅ q p=h\cdot q p=hq group G \mathbb{G} G而设计,其中 q ≈ 2 2 λ , h = 8 q\approx 2^{2\lambda}, h=8 q22λ,h=8

相比于上面的Schnorr签名方案,基于安全性考虑,EdDSA做了如下修改:

  • 1)nonce r r r为根据 s k sk sk和待签名消息 m m m生成的伪随机数。
  • 2)签名中的哈希运算中,额外增加了公钥 p k pk pk,即不再是 H ( R , m ) H(R,m) H(R,m),而是 H ( R , p k , m ) H(R, pk, m) H(R,pk,m)
  • 3)设计为其 s k sk sk安全地复用于 类似于X25519的Diffie-Hellman(DH)密钥交换协议中。【注意: s k = ( a , ( h b , … , h 2 b − 1 ) ) sk=(a,(h_b,\ldots,h_{2b-1})) sk=(a,(hb,,h2b1))中包含了私钥 a a a,以及用于生成nonce r r r b b b-bits—— ( h b , … , h 2 b − 1 ) (h_b,\ldots,h_{2b-1}) (hb,,h2b1),这样使得相同的[Ed25519] secrets也可安全用于做密钥交换。详情可参看Jake Craige 2020年7月博客An Explainer On Ed25519 Clamping

EdDSA需用多个哈希函数:

  • H 1 : { 0 , 1 } 2 λ → { 0 , 1 } 4 λ H_1 : \{0,1\}^{2\lambda} \rightarrow \{0,1\}^{4\lambda} H1:{0,1}2λ{0,1}4λ,
  • H 2 : { 0 , 1 } 2 λ × { 0 , 1 } ∗ → { 0 , 1 } 4 λ H_2 : \{0,1\}^{2\lambda} \times \{0,1\}^* \rightarrow \{0,1\}^{4\lambda} H2:{0,1}2λ×{0,1}{0,1}4λ
  • H 3 : G × G × { 0 , 1 } ∗ → { 0 , 1 } 4 λ H_3 : \mathbb{G} \times \mathbb{G} \times \{0,1\}^* \rightarrow \{0,1\}^{4\lambda} H3:G×G×{0,1}{0,1}4λ

这些函数函数通常可通过合适的域分隔,自单个哈希函数 H : { 0 , 1 } ∗ → { 0 , 1 } 4 λ H : \{0,1\}^* \rightarrow \{0,1\}^{4\lambda} H:{0,1}{0,1}4λ 实例化而来。

E d D S A \mathsf{EdDSA} EdDSA. K e y G e n ( 1 λ ) → ( s k , p k ) \mathsf{KeyGen}(1^\lambda) \rightarrow (sk, pk) KeyGen(1λ)(sk,pk):

  • b ← 2 λ b \gets 2\lambda b2λ
  • k ⃗ ← § { 0 , 1 } b \vec{k} \xleftarrow{\S} \{0,1\}^{b} k § {0,1}b
  • h ⃗ ← H 1 ( k ⃗ ) ∈ { 0 , 1 } 2 b \vec{h} \gets H_1(\vec{k}) \in \{0,1\}^{2b} h H1(k ){0,1}2b
  • a ← 2 b − 2 + ∑ 3 ≤ i ≤ b − 3 2 i h i a \gets 2^{b-2} + \sum_{3 \le i \le b - 3} 2^i h_i a2b2+3ib32ihi
  • s k ← ( a , ( h b , … h 2 b − 1 ) ) sk \gets (a, (h_b, \ldots h_{2b-1})) sk(a,(hb,h2b1))这样该 s k sk sk可同时用于Ed25519签名和X25519密钥交换协议中。
  • p k ← g a pk \gets g^{a} pkga【私钥为 a a a

E d D S A \mathsf{EdDSA} EdDSA. S i g n ( m , s k ) → σ \mathsf{Sign}(m, sk) \rightarrow \sigma Sign(m,sk)σ:

  • Parse ( a , ( h b , … h 2 b − 1 ) ) ← s k (a, (h_b, \ldots h_{2b-1})) \gets sk (a,(hb,h2b1))sk
  • r ← H 2 ( h b , … , h 2 b − 1 , m ) ∈ { 0 , 1 } 2 b r \gets H_2(h_b,\ldots, h_{2b-1}, m) \in \{0,1\}^{2b} rH2(hb,,h2b1,m){0,1}2b
  • R ← g r R \gets g^r Rgr
  • s ← ( r + H 3 ( R , p k , m ) ⋅ a )   m o d   q s \gets (r + H_3(R, pk, m) \cdot a)\bmod q s(r+H3(R,pk,m)a)modq
  • σ ← ( R , s ) \sigma\gets (R, s) σ(R,s)

H 3 H_3 H3中包含公钥 p k pk pk

  • 1)是“一种廉价的方法,可缓解人们对多个公钥可能同时受到攻击的担忧”。
  • 2)另一个有待探索的优势是:可防止对手根据目标签名 σ \sigma σ来查找某公钥 p k pk pk所验证的消息 m m m
    • 如在上面的Schnorr签名方案中,已知任意签名 σ = ( R , s ) \sigma=(R,s) σ=(R,s),对手可选择任意消息 m m m并计算出公钥 p k = ( R / g s ) 1 / H ( R , m ) pk = (R / g^s)^{1/H(R, m)} pk=(R/gs)1/H(R,m)

E d D S A \mathsf{EdDSA} EdDSA. V e r i f y ( m , p k , σ ) → { 0 , 1 } \mathsf{Verify}(m, pk, \sigma) \rightarrow \{0,1\} Verify(m,pk,σ){0,1}:

  • ( R , s ) ← σ (R, s) \gets \sigma (R,s)σ
  • assert g s = ? R ⋅ p k H ( R , p k , m ) g^s \overset{\text{?}}{=} R \cdot pk^{H(R, pk, m)} gs=?RpkH(R,pk,m)

另一种EdDSA高效验签函数为在指数上都乘以cofactor h h h

4.2 Ed25519

所谓Ed25519,为:

  • 基于Edwards 25519曲线的EdDSA签名方案
  • 具有的安全性为 λ = 128 \lambda=128 λ=128
  • 选择了合理的哈希函数

正如2012年论文《High-speed high-security signatures》中所述:

Our recommended curve for EdDSA is a twisted Edwards curve birationally equivalent to the curve Curve25519 […]
We use the name Ed25519 for EdDSA with this particular choice of curve.

最常用的Ed25519为Ed25519-SHA-512,使用SHA2-512作为其哈希函数。
2020年论文The Provable Security of Ed25519: Theory and Practice中有:
在这里插入图片描述

5. Schnorr签名最佳实践及陷阱

在做Schnorr签名实际实现时,通常会有很多微妙之处(即陷阱),详情见:

本文总结为3大陷阱:【其中Ed25519仅可解决陷阱1问题。】

  • 1)陷阱1:安全地生成nonce r r r
  • 2)陷阱2:Non-canonical serialization(非规范序列化)。
  • 3)陷阱3:使用non-prime order group。

5.1 陷阱1:安全地生成nonce r r r

在Schnorr签名中,最应该避免的陷阱在于:

  • 若同一公钥的2个签名复用了相同的nonce r r r,则可提取出相应的公钥。

因此,最重要的一点就是:

  • 基于安全性原因,应对 r r r随机采样获取。

EdDSA中,基于消息和私钥来伪随机确定性的获取 r r r,可解决该问题。

具体的攻击情况为:

  • 假设有对消息 m 1 ≠ m 2 m_1 \ne m_2 m1=m2 的2个签名 σ 1 = ( R , s 1 ) \sigma_1 = (R, s_1) σ1=(R,s1) σ 2 = ( R , s 2 ) \sigma_2 = (R, s_2) σ2=(R,s2),其复用了相同的 r r r,即有:
    R = g r s 1 = r + H ( R , m 1 ) ⋅ s k s 2 = r + H ( R , m 2 ) ⋅ s k \begin{align} R &= g^r\\ s_1 &= r + H(R, m_1) \cdot sk\\ s_2 &= r + H(R, m_2) \cdot sk \end{align} Rs1s2=gr=r+H(R,m1)sk=r+H(R,m2)sk
    则攻击者可按如下方式提取出私钥 s k sk sk
    s 1 − s 2 H ( R , m 1 ) − H ( R , m 2 ) = H ( R , m 1 ) ⋅ s k − H ( R , m 2 ) ⋅ s k H ( R , m 1 ) − H ( R , m 2 ) = s k ⋅ ( H ( R , m 1 ) − H ( R , m 2 ) ) H ( R , m 1 ) − H ( R , m 2 ) = s k \begin{align} \frac{s_1 - s_2}{H(R, m_1) - H(R, m_2)} &= \frac{H(R, m_1)\cdot sk - H(R, m_2)\cdot sk}{H(R, m_1) - H(R, m_2)}\\ &= \frac{sk\cdot(H(R, m_1) - H(R, m_2))}{H(R, m_1) - H(R, m_2)}\\ &= sk \end{align} H(R,m1)H(R,m2)s1s2=H(R,m1)H(R,m2)H(R,m1)skH(R,m2)sk=H(R,m1)H(R,m2)sk(H(R,m1)H(R,m2))=sk

m 1 ≠ m 2 m_1\ne m_2 m1=m2 H H H 为抗碰撞哈希函数,则以上公式中分母不为0,该攻击具有压倒性概率可成功。即使采用 σ ′ = ( e , s ) \sigma'=(e,s) σ=(e,s)格式的Schnorr签名,该攻击也仍成立。

5.2 陷阱2:Non-canonical serialization(非规范序列化)

Non-canonical serialization(非规范序列化)陷阱在于:

  • 在大多数学术论文中,并不区分group元素(或域元素)及其序列化为字节数组 二者之间的差别。
  • 然而开发者在实现Schnorr签名时,必须理解这些group(或域)元素序列化以及反序列化时的陷阱:
    • 以避免签名malleability(延展性)
    • 以及,与其它库保持兼容。

如对Schnorr签名中的 s ∈ Z p s\in \mathbb{Z}_p sZp做反序列化:

  • 直白的代码将不对字节数组内所编码的正整数做检查,即是否为 < p <p <p。这样使得对于相同的 s s s有2种不同的字节表示。从而使得对 m m m的有效Schnorr签名 σ \sigma σ,可被攻击者攻击为对 m m m的另一有效但不同的Schnorr签名 σ ′ \sigma' σ

这样的延展性攻击,对于某些应用——假设对某消息有且仅有一个有效签名,来说,会有很大的问题。在过去,此类攻击可能被用来从(实现不当的)加密货币交易所中抽走资金,详情见2014年论文Bitcoin Transaction Malleability and MtGox

建议:

  • 开发者需确保每个group(或域)元素具有单个唯一的规范序列化表示为字节数组,且其反序列化仅接受该规范表示。
  • Ristretto255为对椭圆曲线group提供规范序列化反序列化的库。

5.3 陷阱3:使用non-prime order group

陷阱3:使用non-prime order group:

  • 实际上在大多数学术论文中,都作为一个重要假设:
    • G \mathbb{G} G为prime-order group。

而Ed25519为最流行的Schnorr签名实现,其并不使用prime-order group。

  • 其使用composite order group,其order为 h ⋅ q h\cdot q hq,其中 q q q为prime 且 h = 8 h = 8 h=8 为cofactor。
  • 在实际做Schnorr批量验签时,会存在单个签名可验证通过,而批量验证不通过的问题。详情见Henry de Valence 2020年10月博客 It’s 255:19AM. Do you know what your validation criteria are?

建议:

  • 在项目中,应尽量避免基于non-prime order group实现Schnorr签名(即避免Ed25519),并采用像Schnorrkel(https://github.com/w3f/schnorrkel(Rust))那样使用prime-order group的Schnorr签名变种。

6. 小结

本文介绍了Schnorr签名及其实践陷阱:

  • nonce复用攻击
  • 批量验签
  • Schnorr签名替代格式 ( e , s ) (e,s) (e,s)
  • 等等

参考资料

[1] Alin Tomescu 2024年5月31日博客 Schnorr signatures: everything you wanted to know, but were afraid to ask!

附录:ECDSA公钥恢复

ECDSA对消息 m m m的签名流程为:【详情见:ECDSA VS Schnorr signature VS BLS signature

  • 1)计算消息 m m m的hash值: e = h a s h ( m ) e=hash(m) e=hash(m)。(hash函数可为SHA-2,输出转换为数值。)
  • 2)若group order n n n的bit length为 L n L_n Ln,则取 e e e值最左侧的 L n L_n Ln bits赋值给 z z z。(注意, z z z值可以比 n n n大,但bit length不能比 n n n的长。)
  • 3)选择随机数 k ∈ R [ 1 , n − 1 ] k\in_R [1,n-1] kR[1,n1]。(注意,不信任一般的随机数生成器,因为不好的RNG有太多的failures和vulnerabilities,可采用RFC6979 根据 p k pk pk m m m来计算deterministic k k k。)(如:2013年8月,安卓Bit0coin钱包因使用了错误的随机数生成器,引起私钥泄露,导致资金损失;2010年12月,索尼PS3游戏机因错误的使用了静态而不是随机的 k k k值,导致其ECDSA私钥泄露。)
  • 4)计算curve point ( x 1 , y 1 ) = k × G (x_1,y_1)=k\times G (x1,y1)=k×G
  • 5)计算 r = x 1 m o d    n r=x_1\mod n r=x1modn,若 r = 0 r=0 r=0,则跳转继续执行步骤3)。
  • 6)计算 s = ( z + r ⋅ s k ) / k m o d    n s=(z+r\cdot sk)/k \mod n s=(z+rsk)/kmodn,若 s = 0 s=0 s=0,则跳转继续执行步骤3)。
  • 7)最终的签名为 ( r , s ) (r,s) (r,s)。(注意, ( r , − s m o d    n ) (r,-s\mod n) (r,smodn)也为有效签名。)
    【根据 BIP-62 可知,为了解决ECDSA签名的malleability问题,可对签名中的 s s s值进行约束,限定 s s s值不高于曲线order的一半。】

所谓ECDSA公钥恢复,是指可根据签名 ( r , s ) (r, s) (r,s)派生出公钥 p k pk pk——DerivedAddress

ECDSA verification, P2PKH uncompressed address

  • 1)Set r = DecodedSignature[1:33]. If r ≥ n or r == 0, fail verification with an error similar to “Invalid ECDSA signature parameters”.
  • 2)Set s = DecodedSignature[33:65]. If s ≥ n or s == 0, fail verification with an error similar to “Invalid ECDSA signature parameters”.
  • 3)Set z = SHA256(Message)
  • 4)Set recID = Header AND 0x3
  • 5)If recID AND 0x2 == 0, set x = r, else set x = r+n
  • 6)Set x = (x^3 + 7) mod p
  • 7)Set y = x^((p+1)/4) mod p
  • 8)Calculate the correct parity of y using the ‘recID’:
    • If (is_even(beta) and is_odd(recID)) or (is_odd(beta) and is_even(recID)), set y = p-y.
  • 9)Set R = (x,y)
  • 10)Set e = (-int(z)) % n
  • 11)Set PublicKey = (Rs + Ge) * modinv(r, n)
  • 12)Compute EncodedPublicKey = “04” || hex(x) || hex(y)
  • 13)Compute AddressHash = RIPEMD160(SHA256(EncodedPublicKey)
  • 14)Compute DerivedAddress = Base58Check(hex(00) || AddressHash).
  • 15)If DerivedAddress == Address, succeed verification. Else fail verification with an error similar to “Wrong address for signature”.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值