AlexiaChen / AlexiaChen.github.io

My Blog https://github.com/AlexiaChen/AlexiaChen.github.io/issues
87 stars 11 forks source link

基于Schnorr签名的盲签名方案 #166

Open AlexiaChen opened 1 year ago

AlexiaChen commented 1 year ago

Schnorr盲签名

前言

之前有写过Schnorr签名其实就是一种零知识证明协议,都会一个challenge生成 https://github.com/AlexiaChen/AlexiaChen.github.io/issues/123 也写过盲签名的大概原理,就是让签名者不知道所 签名的明文消息m,也不知道签名后的签名数据是什么。https://github.com/AlexiaChen/AlexiaChen.github.io/issues/132

下面我们就讲解一种基于Schnorr的盲化签名方案。盲化签名本质上就是要对盲化函数和去盲函数进行选择。

实现

因为盲签名一般是两方协议,有客户和签名者的概念,我们这里把客户变成User(Client),签名者变成Server,来讨论。

前提条件:

假设Server有一个私钥$x$,公钥 $X = x * G$. 当然,G就是椭圆曲线上的生成元(基点)。

  1. Server生成随机数nonce

Server生成一个随机的秘密值$k$和公有nonce $R = k*G$ 。 R当然就是一个曲线上的随机点了,然后把着两个值保存下来。然后把nonce $R$和公钥$X$发送给User(Client)。

  1. Client生成盲化因子

User选择一段消息$m$,这个消息也就是待签名的数据明文。然后生成三个随机标量值$\alpha, \beta, t$, 这些标量将用来盲化(伪装)我们要求Server端签署的消息$m$。

当然这些标量,包括nonce的bit长度都是一样的,最好是uint256表示。R虽然是一个随机点,但是也可以表示成标量。

  1. Client盲化这些因子
  1. Server签名

Server通过自己的私钥$x$和随机秘密值$k$生成签名$s = k + c' * x$。然后把签名$s$发给Client。

  1. Client去盲签名s

Client利用之前的盲化因子和challenge c去盲s: $s' = s + \alpha + c*t$。 去盲后的签名实际上就是$(R', s')$

  1. 验证签名

这里的验证签名,是除了client和server,其他任何人都可以验证,毕竟盲化的公钥$X'$是公开的.验证签名其实就是验证以下公式是否相等:

$$ VerifySignature(R',s', c, X') := s' G = R' + c X' $$

注意,这里的c是直接用别人共享过来值c,不是通过Hash计算出来的,因为验签人也不知道m是什么。

各类数值的十六进制的具体代入例子

公式推导

d316700c2c00f5d676e96c4fef37048

参考