参考:BLS数字签名算法介绍及拓展
G 1 , G 2 G_1,G_2 G1,G2 是阶为 p p p 的 乘法循环群 。生成元分别是 g 1 , g 2 g_1, g_2 g1,g2
e e e 是 双线性映射:G1 * G2 -> GT ,
安全 h a s h hash hash函数:h:{0,1}*-> G1
公开参数是 ( G 1 , G 2 , G T , e , g 1 , g 2 , p , h ) (G_1, G_2, G_T, e, g_1, g_2,p,h) (G1,G2,GT,e,g1,g2,p,h)
(1) 选择一个随机数 x ∈ Z P x∈Z_P x∈ZP,私钥 S K = x S_K=x SK=x (secret key),计算公钥 P K = v = g 2 x ∈ G 2 P_K=v=g_2^x∈G_2 PK=v=g2x∈G2
对消息 M M M签名: s i g = h ( M ) ∗ x sig=h(M)*x sig=h(M)∗x
验证等式是否成立:
e ( s i g , g 2 ) = e ( h ( M ) , v ) e(sig,g_2)=e(h(M),v) e(sig,g2)=e(h(M),v)
最简单的实现门限签名的方式就是:SSS(Shamir Secret Share)
SSS 的核心是:拉格朗日插值法
拉格朗日插值法:
已知一条 n − 1 n-1 n−1次曲线上的 n n n个点 ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . . , ( x n , y n ) (x_1,y_1), (x_2,y_2), ...., (x_n,y_n) (x1,y1),(x2,y2),....,(xn,yn) .可以使用拉格朗日插值法恢复这条曲线方程,具体如下:
y = ( x − x 2 ) ( x − x 3 ) . . . ( x − x n ) ( x 1 − x 2 ) ( x 1 − x 3 ) . . . ( x 1 − x n ) y 1 + ( x − x 1 ) ( x − x 3 ) . . . ( x − x n ) ( x 2 − x 1 ) ( x 2 − x 3 ) . . . ( x 2 − x n ) y 2 + . . . + ( x − x 1 ) ( x − x 2 ) . . . ( x − x n − 1 ) ( x n − x 1 ) ( x n − x 2 ) . . . ( x n − x n − 1 ) y n y = \dfrac{(x-x_2)(x-x_3)...(x-x_n)}{(x_1-x_2)(x_1-x_3)...(x_1-x_n)}y_1+\dfrac{(x-x_1)(x-x_3)...(x-x_n)}{(x_2-x_1)(x_2-x_3)...(x_2-x_n)}y_2+...+\dfrac{(x-x_1)(x-x_2)...(x-x_{n-1})}{(x_n-x_1)(x_n-x_2)...(x_n-x_{n-1})}y_n y=(x1−x2)(x1−x3)...(x1−xn)(x−x2)(x−x3)...(x−xn)y1+(x2−x1)(x2−x3)...(x2−xn)(x−x1)(x−x3)...(x−xn)y2+...+(xn−x1)(xn−x2)...(xn−xn−1)(x−x1)(x−x2)...(x−xn−1)yn
1. 先任意选择一条 t -1=2 次曲线,以这条曲线在 x=0 处的值作为秘密。
2. 然后任意取出曲线上的 n = 4 个点 (1,2),(2,5), (3,10),(4,17) 后,任选其中三个点后恢复出来的曲线是一样的。
3. 因此,我可以将这四个点(横坐标分别是 1、2、3、4)发送给四个不同的人,这样就是一个 3-of-4 的秘密分享了。
有了以上知识,应该可以理解基于 BLS 签名的门限签名算法 。
门限签名的通俗理解是:在一个签名者群体中,有超过 m (门限) 个签名者对一条消息进行签名就可以得到这个群体对这条消息的签名,并且认为 这个群体 对这条消息进行了验证。
G 1 , G 2 G_1,G_2 G1,G2 是阶为 p p p 的 乘法循环群 。生成元分别是 g 1 , g 2 g_1, g_2 g1,g2
e e e 是 双线性映射:G1 * G2 -> GT ,
安全 h a s h hash hash函数:h:{0,1}*-> G1
公开参数是 ( G 1 , G 2 , G T , e , g 1 , g 2 , p , h ) (G_1, G_2, G_T, e, g_1, g_2,p,h) (G1,G2,GT,e,g1,g2,p,h)
这步由 密钥生成中心 完成
(1)密钥生成中心,选择系统主私钥,计算系统主公钥。
(2)分别计算 节点 的 私钥 和公钥 。
(3)公开 主公钥 M P K MPK MPK 及所有用户的公钥
(1)用户 u i u_i ui计算对消息 M M M签名: σ i = h ( M ) x i \sigma_i=h(M)^{x_i} σi=h(M)xi;
(2)广播 σ i \sigma_i σi;
(3)用户间签名验证:用户 u i u_i ui收到了来自 u j u_j uj的签名 σ j \sigma_j σj后,首先验证签名的正确性: e ( σ j , g 2 ) = e ( h ( M ) , v j ) e(\sigma_j,g_2)=e(h(M),v_j) e(σj,g2)=e(h(M),vj),如果签名正确则记录下来;
(4)待收集到 t 个不同用户的正确签名后,用户计算完整的签名:
由拉格朗日差值公式可知,任意 t 个用户所产生的完整签名相同
e ( σ , g 2 ) ? = e ( h ( M ) , M P K ) e(σ, g_2)? = e(h(M), MPK) e(σ,g2)?=e(h(M),MPK)
关于JPBC库安装,可在B站看到相关视频
package com.CYQ.signatures.bls;
import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.jpbc.Field;
import it.unisa.dia.gas.jpbc.Pairing;
import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;
//BLS签名(单个)
public class BLS {
public static void main(String[] args){
// 初始化
Pairing bp = PairingFactory.getPairing("a.properties");
Field G1 = bp.getG1();
Field Zr = bp.getZr();
Element g = G1.newRandomElement();
Element x = Zr.newRandomElement();//私钥
Element g_x = g.duplicate().powZn(x);//公钥
//签名
String m = "message";//签名的消息!
byte[] m_hash = Integer.toString(m.hashCode()).getBytes();
Element h = G1.newElementFromHash(m_hash, 0, m_hash.length);
Element sig = h.duplicate().powZn(x);//签名
//验证
Element pl = bp.pairing(g, sig);//g ,sig均为公共参数
Element pr = bp.pairing(h, g_x);//h,公钥均为公共参数
if (pl.isEqual(pr))
System.out.println("Yes");
else
System.out.println("No");
}
}
此文章参考了CSDN上多位博主的文章,可以看作一篇总结文章,此处难以一一列举,望见谅。
如若侵权,请联系,会删除的!
参考:
1、拉格朗日中值定理