GMSSL SM9-加密流程
源代码参见\GmSSL-master\engines\sm_standard\sm9\sm9_standard_enc.c
1.初始化
SM9_standard_init();
2.生成密钥:
SM9_standard_generateencryptkey(hid, IDB, strlen(IDB), ke, Ppub, deB);
hid:用一个字节表示的加密私钥生成函数识别符,由KGC 选择并公开。 函数中为0x03,具体为什么现在不清楚
*IDB = "Bob";字符串;用户标识;
strlen(IDB):字符串长度;
ke:随机数,加密主私钥
Ppub:加密主公钥(待获取值),64字节长度
deB:128字节长度,用户B的加密私钥
2.1
SM9_standard_h1(Z, Zlen, N, h1);杂凑密码函数H1()的实现,处理流程参见《SM9标识密码算法第四部分密钥封装机制和公钥加密算法》P5 3.4.2.2密码函数H1()。
Z:用户标识+私钥函数识别符
Zlen:Z的长度
N:群的阶(待获取值)
h1:(待获取值)
标准写的是步骤2:计算 hlen=8*([5*(log2n))/32]; 他是位长
gmssl写的是hlen = (int)ceil((5.0 * logb2(n)) / 32.0); 他是字节长
2.1.1
SM3_kdf(ZH, ZHlen, hlen, ha);
使用SM3进行密钥派生,入参为标识
2.1.2
for(i = hlen - 1; i >= 0; i--)//key[从大到小]
{
premult(i256, ha[i], tmp);
add(hh, tmp, hh);
premult(i256, 256, i256);
divide(i256, n1, tmp);
divide(hh, n1, tmp);
}
若klen/v是整数,令 Ha!klen/v=Haklen/v,
否则令 Ha!klen/v为Haklen/v最左边的(klen(vklen/v))比特;
计算出h1;
2.2
//Ppub=[ke]P2
ecurve_mult(ke, P1, Ppub);
计算P2?应该是P1吧的ke倍点,得到Ppub作为签名主公钥;
2.3产生B用户的私钥dEB
//deB=[t2]P2
ecn2_copy(&P2, &dEB);
ecn2_mul(t2, &dEB);
综上,私钥生成的过程为:
KGC产生一个随机数作为主私钥;
群1的生成元的随机数倍点作为主公钥公开,KGC秘密保存随机数(主私钥);
用户的标识与密钥生成函数识别符的字符串进行哈希之后,与主私钥进行加法运算,作为用户的私钥。
3.加密,加密流程见《SM9标识密码算法第四部分密钥封装机制和公钥加密算法》P8 5.1加密算法及流程
SM9_standard_encrypt(hid, IDB, std_message, strlen(std_message), rand, EncID, k1_len, k2_len, Ppub, C, &C_len);
hid:用一个字节表示的加密私钥生成函数识别符,由KGC 选择并公开。 函数中为0x03,具体为什么现在不清楚
*IDB = "Bob";字符串;用户标识;
std_message:"Chinese IBE standard";待加密的消息;
strlen(std_message):待加密消息的长度;
rand:加密算法随机数
EncID://0,stream //1 block
k1_len:
k2_len:
Ppub:加密主公钥(输出值),64字节长度
C:一个1000个元素的数组,存放加密的密文
&C_len:C_len the length of C
3.1. SM9_standard_h1(Z, Zlen, N, h);
//Step1:calculate QB=[H1(IDB||hid,N)]P1+Ppube(加密主公钥)
3.2. //Step2:randnom
bytes_to_big(BNLEN, rand, r);
3.3.//Step3:C1=[r]QB
ecurve_mult(r, QB, C1);
3.4. //Step4:g = e(P2, Ppub-e)
ecap(P2, Ppube, para_t, X, &g)找到双线性对,P2和Ppube的映射。
3.5. //Step5:calculate w=g^r
w = zzn12_pow(g, r);
3.6.//Step:6-1: calculate K=KDF(C1||w||IDB,klen)
//Step:6-2: calculate C2=M^K1,and test if K1==0?
3.7.//Step7:calculate C3=MAC(K2,C2)消息认证,使用的SM3_256哈希算法。
密文是密钥(私钥)+消息认证码+密文(被加密的明文)组成,加密明文可以使用序列密码算法或者分组密码算法。
加密算法
设需要发送的消息为比特串 M,mlen为 M 的比特长度,K1_len为分组密码算法中密钥 K1的比特长
度,K2_len为函数 MAC(K2,Z)中密钥K2的比特长度。
为了加密明文 M 给用户 B,作为加密者的用户 A应实现以下运算步骤:
A1: 计算群 1中的元素 QB=[H1(IDB||hid,N)]P1+Ppub-e;
A2: 产生随机数 r[1,N1];
A3: 计算群 1中的元素 C1=[r]QB,将C1 的数据类型转换为比特串;
A4: 计算群 T中的元素g=e(Ppub-e,P2);
A5: 计算群 T中的元素w=gr,按将w 的数据类型转换为比特串;
A6: 按加密明文的方法分类进行计算:
a) 如果加密明文的方法是基于密钥派生函数的序列密码算法,则
1) 计算整数 klen=mlen+K2_len,然后计算K=KDF(C1||w||IDB,klen)。令K1 为K 最左边
的 mlen 比特,K2为剩下的K2_len比特,若 K1为全0 比特串,则返回 A2;
9
2) 计算 C2=M⊕K1。
b) 如果加密明文的方法是结合密钥派生函数的分组密码算法,则
1) 计算整数 klen=K1_len+K2_len,然后计算K=KDF(C1||w||IDB,klen)。令K1 为K 最左
边的 K1_len比特,K2为剩下的 K2_len比特,若 K1为全 0 比特串,则返回A2;
2) 计算 C2=Enc(K1,M)。
A7: 计算 C3=MAC(K2,C2);
A8: 输出密文 C=C1||C3||C2。