【无标题】

身份基加密 (Identity based Encryption)算法

论文 Identity-Based Encryption from the Weil Pairing

Setup

  1. 生成pairing相关公共参数 < e , G 1 , G T , Z r > <e,G_1, G_T,Z_r> <e,G1​,GT​,Zr​>
  2. 选取随机数 x ∈ Z r x\in Z_r x∈Zr​ 作为系统主密钥 m s k msk msk
  3. 选取随机元素 g ∈ G 1 g\in G_1 g∈G1​作为生成元,计算公共参数 g x g^x gx。因此,有系统公钥 p k = < g , g x > pk=<g,g^x> pk=<g,gx>
  4. 选取公共哈希函数 H 1 : { 0 , 1 } ∗ → G 1 ∗ H_1:\{0,1\}^*\rightarrow G_1^* H1​:{0,1}∗→G1∗​, H 2 : G T → { 0 , 1 } n H_2:G_T \rightarrow \{0,1\}^n H2​:GT​→{0,1}n

KeyGen

  1. 给定用户身份 I D ∈ { 0 , 1 } ∗ ID\in \{0,1\}^* ID∈{0,1}∗,将其映射为群 G 1 G_1 G1​上的元素。即计算 Q I D = H 1 ( I D ) Q_{ID}=H_1(ID) QID​=H1​(ID)
  2. 由系统主密钥 x x x计算此 I D ID ID对应的私钥为 s k = Q I D x sk=Q_{ID}^x sk=QIDx​

Encrypt

  1. 针对目标用户身份 I D ∈ { 0 , 1 } ∗ ID\in \{0,1\}^* ID∈{0,1}∗,计算 Q I D = H 1 ( I D ) Q_{ID}=H_1(ID) QID​=H1​(ID)
  2. 选取随机数 r ∈ Z r r\in Z_r r∈Zr​,计算密文组件 C 1 = g r C_1=g^r C1​=gr
  3. 计算 g I D = e ( Q I D , g x ) r g_{ID}=e(Q_{ID},g^x)^r gID​=e(QID​,gx)r
  4. 计算密文组件 C 2 = M ⊕ H 2 ( g I D ) C_2=M \oplus H_2(g_{ID}) C2​=M⊕H2​(gID​),其中 M ∈ { 0 , 1 } n M \in \{0,1\}^n M∈{0,1}n是明文数据
  5. 最终的密文为 < C 1 , C 2 > <C_1,C_2> <C1​,C2​>

Decrypt

  1. 解密的关键在于恢复 g I D g_{ID} gID​
  2. e ( s k , C 1 ) = e ( Q I D x , g r ) = e ( Q I D , g ) x r = g I D e(sk,C_1)=e(Q_{ID}^x,g^r)=e(Q_{ID},g)^{xr}=g_{ID} e(sk,C1​)=e(QIDx​,gr)=e(QID​,g)xr=gID​
  3. 恢复明文 M = C 2 ⊕ H 2 ( e ( s k , C 1 ) ) M=C_2 \oplus H_2(e(sk,C_1)) M=C2​⊕H2​(e(sk,C1​))

代码实现注意事项

1.选择用Properties保存是因为支持键值读取,比如密文可能包含多个组件,方便分别读取每个组件。
2.方法SetProperties的第二个参数必须为String类型,因此需要先将要保存的元素转换为String类型后存储。

//写入文件
Properties pkProp = new Properties();
//pkProp.setProperty("g", new String(g.toBytes()));  //可以用这种方式将g转换为字符串后写入,但文件中会显示乱码
//为了避免乱码问题,统一采用Base64编码为可读字符串形式
pkProp.setProperty("g", Base64.getEncoder().encodeToString(g.toBytes()));
pkProp.setProperty("gx", Base64.getEncoder().encodeToString(gx.toBytes()));
storePropToFile(pkProp, pkFileName);  

//从文件读取
Properties pkProp = loadPropFromFile(pkFileName);
String gString = pkProp.getProperty("g");
Element g = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(gString)).getImmutable();
String gxString = pkProp.getProperty("gx");
Element gx = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(gxString)).getImmutable();

3.bp.getG1().newElementFromBytes()bp.getG1().newElementFromHash()用法。前者一般用于将一个恢复一个通过bytes到处的元素,比如上图的代码中用于恢复ggx。后者用于从一个hash得到的字节数组中构造一个新元素,如下代码中用于将ID映射为群元素。

byte[] idHash = sha1(id);
Element QID = bp.getG1().newElementFromHash(idHash, 0, idHash.length).getImmutable();

4.算法实现过程中,遵从原文,密文组件的计算采用了异或方式,即 C 2 = M ⊕ H 2 ( g I D ) C_2=M \oplus H_2(g_{ID}) C2​=M⊕H2​(gID​)。在后面的ABE方案中,一般都是直接计算 C 2 = M ⋅ g I D C_2=M \cdot g_{ID} C2​=M⋅gID​,这样仿真起来会更简单一些。

上一篇:拟牛顿法(Python实现)


下一篇:Tendermint的安装(Windows 10)