密码学——Schnorr签名算法

一、基本知识

1.1 概述

Schnorr签名算法最初是由德国密码学家ClausSchnorr于2008年提出的,在密码学中,它是一种数字签名方案,以其简单高效著称,其安全性基于某些离散对数问题的难处理性。

1.2 椭圆曲线上的计算

密码学中,常用以下形式的椭圆曲线: E : y 2 = x 3 + a x + b ( m o d   p ) E: y^2= x^3+ax+b(mod\ p) E:y2=x3+ax+b(mod p) 同时要求 4 a 3 + 27 b 2 ≠ 0 4a^3+27b^2 ≠0 4a3+27b2=0。其中p为一个大素数,a、b、x和y均在有限域 G F ( p ) GF(p) GF(p)中,即从 { 0 , 1 , ⋅ ⋅ ⋅ , p − 1 } \{0,1,···,p-1\} {0,1,⋅⋅⋅,p1}中取值。该曲线常用 E p ( a , b ) E_{p}(a,b) Ep(a,b)表示。若该曲线上只有有限个离散点,设为N个,则椭圆曲线的阶为N。N越大,椭圆曲线安全性越高。椭圆曲线的阶可通过schoof算法计算求得。
椭圆曲线 E : y 2 = x 3 − x + 1 E: y^2= x^3-x +1 E:y2=x3x+1图形如下:
 y^2= x^3-x +1


加法规则

椭圆曲线 E p ( a , b ) E_{p}(a,b) Ep(a,b)在如下定义的加法规则构成Abel群(交换群)。

  • O + O = O Ο + Ο = Ο O+O=O
  • ∀ P = ( x , y ) ∈ E p ( a , b ) ∀P=(x,y)∈E_{p}(a,b) P=(x,y)Ep(a,b),有 P + O = O + P = P P +Ο =Ο + P = P P+O=O+P=P
  • ∀ P = ( x , y ) ∈ E p ( a , b ) ∀P=(x,y)∈E_{p}(a,b) P=(x,y)Ep(a,b),有 P + ( − P ) = O P + (-P) =Ο P+(P)=O P P P的逆为 − P = ( x , − y ) -P = (x,-y) P=(x,y)
  • ∀ P = ( x 1 , y 1 ) , Q = ( x 2 , y 2 ) ∈ E p ( a , b ) ∀P=(x_{1},y_{1}),Q=(x_{2},y_{2})∈E_{p}(a,b) P=(x1,y1),Q=(x2,y2)Ep(a,b),则 P + Q = R = ( x 3 , y 3 ) ∈ E p ( a , b ) P + Q = R = (x_{3},y_{3})∈E_{p}(a,b) P+Q=R=(x3,y3)Ep(a,b),其中 x 3 = λ 2 − x 1 − x 2 , y 3 = λ ( x 1 − x 3 ) − y 1 x_3=λ^2-x_1-x_2 ,y_3=λ(x_1-x_3 )-y_1 x3=λ2x1x2,y3=λ(x1x3)y1

  • 相同点相加计算R点在这里插入图片描述
    • 不同点相加计算R点
      在这里插入图片描述
乘法规则
  • ∀ k ∈ Z , ∀ P ∈ E p ( a , b ) ∀k∈Z,∀P∈E_p (a,b) kZ,PEp(a,b),有 k P = P + ⋅ ⋅ ⋅ + P ( k 个 P 相加 ) kP=P+···+P(k个P相加) kP=P+⋅⋅⋅+P(kP相加)
  • ∀ s , t ∈ Z , ∀ P ∈ E p ( a , b ) ∀s,t∈Z, ∀P∈E_p (a,b) s,tZ,PEp(a,b),有 ( s + t ) P = s P + t P , s ( t P ) = ( s t ) P (s+t)P=sP+tP,s(tP)=(st)P (s+t)P=sP+tP,s(tP)=(st)P

除了无限远的点 O Ο O外,椭圆曲线 E E E任何可以生成所有点的点都可视为 E E E的生成元,但并非 E E E上所有点都可为生成元。
如何选取生成元

  • 首先分解椭圆曲线阶 n = r × p n = r × p n=r×p,p需要足够大。
  • k = n / p k= n/p k=n/p,随机选取 X ∈ E p ( a , b ) X∈E_p (a,b) XEp(a,b),计算 G = k ⋅ X G = k ·X G=kX
  • G ≠ O G ≠ Ο G=O,则 G G G可为生成元否则重新选择 X X X再次计算。

二、算法细节

2.1 公私钥产生算法( K e y G e n KeyGen KeyGen):
  • 选择一条椭圆曲线 E p ( a , b ) E_{p}(a,b) Ep(a,b) 和基点 G G G
  • 选择私钥 d A d_{A} dA d A < n d_{A}<n dA<n n n n为该 G G G的阶),利用基点 G G G计算公钥 Q A = d A ⋅ G Q_{A}=d_{A} · G QA=dAG
2.2 签名生成算法( S i g n Sign Sign
  • 选择一个随机整数 k ( k < n ) k(k<n) k(k<n);
  • 计算点 R = k ⋅ G = ( x 1 , y 1 ) R=k·G=(x_{1},y_{1}) R=kG=(x1,y1)
  • 计算 σ = k + h a s h ( m ∣ ∣ R ) ⋅ d A ( m o d   n ) \sigma=k + hash(m|| R)·d_{A} (mod \ n) σ=k+hash(m∣∣R)dA(mod n)
  • 得到签名 s = ( R , σ ) s=(R,\sigma) s=(R,σ);
2.3 签名验证算法(Verify):
  • 验证等式: σ ⋅ G ≡ h a s h ( m ∣ ∣ R ) ⋅ Q A + R \sigma · G ≡{hash(m|| R)}·Q_{A} + R σGhash(m∣∣R)QA+R
  • 如果等式成立输出1,否则输出0。

Schnorr签名除了上面一种形式外,还有另外一种形式。

2.4 签名生成算法( S i g n Sign Sign
  • 选择一个随机整数 k ( k < n ) k(k<n) k(k<n);
  • 计算点 R = k ⋅ G = ( x 1 , y 1 ) R=k·G=(x_{1},y_{1}) R=kG=(x1,y1)
  • 计算 α = h a s h ( m ∣ ∣ R ) \alpha=hash(m|| R) α=hash(m∣∣R)
  • 计算 σ = k + h a s h ( m ∣ ∣ R ) ⋅ d A ( m o d   n ) \sigma=k + hash(m|| R)·d_{A} (mod \ n) σ=k+hash(m∣∣R)dA(mod n)
  • 得到签名 s = ( α , σ ) s=(\alpha,\sigma) s=(α,σ);
2.5 签名验证算法(Verify):
  • 计算 R ′ = σ ⋅ G − α ⋅ Q A R^{'}=\sigma·G-\alpha·Q_{A} R=σGαQA
  • 验证等式: h a s h ( m ∣ ∣ R ′ ) ≡ α hash(m|| R^{'}) ≡\alpha hash(m∣∣R)α
  • 如果等式成立输出1,否则输出0。
  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
MIRACL密码库是一个用于实现椭圆曲线密码学算法的库,其中包括了Schnorr签名算法的实现。下面是利用MIRACL密码库进行消息的Schnorr签名的步骤: 1. 选择一个椭圆曲线,确定基点G和阶n 2. 随机选择一个私钥x,并计算公钥y = x * G 3. 对待签名的消息m进行哈希,得到哈希值h 4. 随机选择一个k,并计算R = k * G 5. 计算e = H(R || y || m),其中||表示连接操作 6. 计算s = k + e * x 7. 签名为(R, s) 在MIRACL密码库中,可以使用以下代码实现Schnorr签名: ```c #include <miracl/miracl.h> int main() { miracl *mip = mirsys(1000, 16); mip->IOBASE = 16; /* 选择椭圆曲线、基点G和阶n */ epoint *G = epoint_init(); big n = mirvar(0); ecurve2_init(a, b, p, MR_PROJECTIVE); epoint2_set(x, y, 0, G); cinstr(n, "r"); // 阶n /* 随机选择私钥x,并计算公钥y */ big x = mirvar(0); big y = mirvar(0); strong_bigrand(&rng, n, x); ecurve2_mult(x, G, y); /* 对待签名消息m进行哈希,得到哈希值h */ char *m = "Hello, world!"; hash_and_reduce(m, h, SHA256); /* 随机选择k,并计算R = k * G */ big k = mirvar(0); epoint *R = epoint_init(); strong_bigrand(&rng, n, k); ecurve2_mult(k, G, R); /* 计算e = H(R || y || m) */ big e = mirvar(0); sha256_init(&sh); sha256_process(&sh, (char*)epoint2_x(R), 32); sha256_process(&sh, (char*)epoint2_y(R), 32); sha256_process(&sh, (char*)epoint2_x(y), 32); sha256_process(&sh, m, strlen(m)); sha256_hash(&sh, (char*)e); reduce(e, n); /* 计算s = k + e * x */ big s = mirvar(0); multiply(e, x, e); add(k, e, s); reduce(s, n); /* 签名为(R, s) */ printf("Signature: (%s,%s)\n", epoint2_x(R), s); return 0; } ``` 需要注意的是,上述代码中的a、b、p、r等参数需要根据具体的椭圆曲线进行设置。另外,该代码中的哈希函数使用了SHA256,可以根据需要进行更改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值