Open AlexiaChen opened 1 year ago
之前有写过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就是椭圆曲线上的生成元(基点)。
Server生成一个随机的秘密值$k$和公有nonce $R = k*G$ 。 R当然就是一个曲线上的随机点了,然后把着两个值保存下来。然后把nonce $R$和公钥$X$发送给User(Client)。
User选择一段消息$m$,这个消息也就是待签名的数据明文。然后生成三个随机标量值$\alpha, \beta, t$, 这些标量将用来盲化(伪装)我们要求Server端签署的消息$m$。
当然这些标量,包括nonce的bit长度都是一样的,最好是uint256表示。R虽然是一个随机点,但是也可以表示成标量。
Server通过自己的私钥$x$和随机秘密值$k$生成签名$s = k + c' * x$。然后把签名$s$发给Client。
Client利用之前的盲化因子和challenge c去盲s: $s' = s + \alpha + c*t$。 去盲后的签名实际上就是$(R', s')$
这里的验证签名,是除了client和server,其他任何人都可以验证,毕竟盲化的公钥$X'$是公开的.验证签名其实就是验证以下公式是否相等:
$$ VerifySignature(R',s', c, X') := s' G = R' + c X' $$
注意,这里的c是直接用别人共享过来值c,不是通过Hash计算出来的,因为验签人也不知道m是什么。
83814f977c81e0d3bce35a0789c90e804fd3e1cb0e6ad71e797ef2adf9a98567
4d6df5468daccafe8a8ca4a7ead25907f47ed76f63e098808141ceea97cb4139
086a1d986288a10efee980f1c54393a49eb7282749f6faf8d41b1a7ec5388f47
ff63ac5c4f8a070eaa7e5ec364579ce81d57c296a94210c9b29baac4d6b55122
02cf069dead6d52f261b0548768201b615c770f55b14c29df425d05d06854b4058
0263a4be2a134b5bd0599f1d9a8fe2270f74677ca5f657302f2e275fc20b481327
1b572e3d1568a340986db8bdf388a97f7c38fb1dce3b7fab9d94f5f01be0c788
db6730485a402e1385a22f49b3c0984a132da02f1ce8d8cda829604002e04b33
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就是椭圆曲线上的生成元(基点)。
Server生成一个随机的秘密值$k$和公有nonce $R = k*G$ 。 R当然就是一个曲线上的随机点了,然后把着两个值保存下来。然后把nonce $R$和公钥$X$发送给User(Client)。
User选择一段消息$m$,这个消息也就是待签名的数据明文。然后生成三个随机标量值$\alpha, \beta, t$, 这些标量将用来盲化(伪装)我们要求Server端签署的消息$m$。
Server通过自己的私钥$x$和随机秘密值$k$生成签名$s = k + c' * x$。然后把签名$s$发给Client。
Client利用之前的盲化因子和challenge c去盲s: $s' = s + \alpha + c*t$。 去盲后的签名实际上就是$(R', s')$
这里的验证签名,是除了client和server,其他任何人都可以验证,毕竟盲化的公钥$X'$是公开的.验证签名其实就是验证以下公式是否相等:
$$ VerifySignature(R',s', c, X') := s' G = R' + c X' $$
注意,这里的c是直接用别人共享过来值c,不是通过Hash计算出来的,因为验签人也不知道m是什么。
各类数值的十六进制的具体代入例子
83814f977c81e0d3bce35a0789c90e804fd3e1cb0e6ad71e797ef2adf9a98567
4d6df5468daccafe8a8ca4a7ead25907f47ed76f63e098808141ceea97cb4139
086a1d986288a10efee980f1c54393a49eb7282749f6faf8d41b1a7ec5388f47
ff63ac5c4f8a070eaa7e5ec364579ce81d57c296a94210c9b29baac4d6b55122
02cf069dead6d52f261b0548768201b615c770f55b14c29df425d05d06854b4058
0263a4be2a134b5bd0599f1d9a8fe2270f74677ca5f657302f2e275fc20b481327
1b572e3d1568a340986db8bdf388a97f7c38fb1dce3b7fab9d94f5f01be0c788
db6730485a402e1385a22f49b3c0984a132da02f1ce8d8cda829604002e04b33
公式推导
参考